Neymar converted a penalty after Mario Gaspar had handled the ball, only for the visitors to equalise through Mateo Musacchio's fierce header three minutes after the break.
Barcelona were finding Villarreal's defence obdurate but they eventually found their way through in the 68th minute when Neymar fired home a simple goal.
Victory takes Barcelona three clear of Atletico and five points ahead of Real Madrid who were held by Osasuna earlier on Saturday.
Barcelona almost went ahead in the sixth minute when Alex Song's close-range volley hit the post, with no home player following up.
Andres Iniesta slid a pass to Neymar who slotted a ball across the box but there was no Barcelona boot there to tap home.
Former Barcelona player Giovanni dos Santos showed good pace for the visitors on his return to the Nou Camp, driving forward and releasing the ball into the area only for the home side to clear.
Villarreal were getting more of a foothold in the game although there was little from either side in terms of creating clear-cut chances.
Barcelona were having problems breaking down an assured Villarreal defence and their breakthrough eventually came from a harsh penalty decision in the 30th minute.
Gaspar could hardly get out of the way of the ball which was driven against his arm by Jordi Alba and the referee pointed to the spot.
Neymar confidently strode up and rolled the ball to the right of the goalkeeper to put Barcelona ahead.
The hosts almost doubled their lead in the 40th minute when Alexis Sanchez controlled a Martin Montoya shot from the edge of the area, turned and shot only for Sergio Asenjo to spread himself and tip the ball round the post.
Villarreal were level three minutes after the break.
Manu Trigueros sent in an inswinging corner which found Musacchio who had got ahead of his marker, bending to reach the ball and planting a bullet header past Jose Pinto.
Dos Santos then fired inches past the post for Villarreal.
Barcelona went close to regaining the lead when Cesc Fabregas ran on to a defence-splitting pass, only for Asenjo to block his shot with his feet.
They did, though, go back in front midway through the half through Neymar.
Fabregas dinked a ball into the penalty area and over the defence which found Sanchez, who had broken the offside trap. He cushioned the ball to Neymar who had the simple task of firing home.
Neymar then went close to claiming a third goal when pace took him beyond the defence, and although the angle was acute he forced Asenjo to block with his feet.
Asenjo then tipped Iniesta's volley from the edge of the area wide of the post.