Barcelona's first win in three rounds left it one point above second-placed Sevilla, which rallied to a 1-1 draw at fourth-placed Alaves.
Injury-depleted Barcelona got goals from Gerard Pique and rarely used reserve player Carles Alena in each half at Camp Nou.
With the hosts missing striker Luis Suarez, France forward Ousmane Dembele led Barcelona with his speedy incursions from the right flank.
Dembele crossed for Pique to head in his 36th-minute opener. The defender sent the ball off the turf and past goalkeeper Sergio Asenjo, who got a hand on the ball but couldn't keep it out.
Lionel Messi was the playmaker in the 87th for Alena, who had come on for Arturo Vidal.
Alena recovered the ball in midfield and laid the ball off to Messi. The Argentine returned it by meeting Alena's run forward with a threaded pass through four defenders. The 20-year-old Alena completed the move with a fine finish by chipping the ball over the onrushing Asenjo.
"(Alena) has won his move up from the reserve team to the first team," coach Ernesto Valverde said. "We needed his energy at that moment of the match."
Villarreal's only clear scoring chance came early when Gerard Moreno hit the post after some lax defending by Clement Lenglet.
SEVILLA STUMBLES Sevilla couldn't hold on to first place in the standings that it won last round.
Jonathan Rodriguez stabbed in a cross by Jonathan Calleri to give Alaves the lead in the 37th. Sevilla needed playmaker Pablo Sarabia to come off the bench to help rescue a point, crossing for Wissam Ben Yedder to level in the 78th.
Alaves again proved to be one of the toughest teams to beat, staying undefeated in all seven home matches this season.
ATLETICO HELD Atletico Madrid needed a late own-goal to salvage a 1-1 draw at Girona as it recorded a fourth straight draw away from home in the league for Diego Simeone's team.
Atletico remained in third place, three points behind Barcelona.
Girona striker Christian Stuani scored his league-leading 11th goal of the season by converting a spot kick just before halftime after being fouled by Atletico goalkeeper Jan Oblak. A video review awarded the penalty after the referee had initially ruled that the foul was outside the area.
Simeone sent on forwards Gelson Martins and Angel Correa to spark a comeback, and Correa came through when he recovered the ball and quickly sent a long ball forward to Diego Costa. Defender Jonas Ramalho tried to impede Costa from striking the ball, only to tap it into his own net in the 82nd.
Saul Niguez hit the crossbar for Atletico in the first half.
Girona lost goalkeeper Yassine Bounou to a leg injury midway through the second half, but replacement Gorka Iraizoz made a fingertip save to deny Niguez in the 77th.
"We could have lost, we could have won, the league is very tough. Every match is complicated," Simeone said. "There are no easy rivals."
Elsewhere, Real Betis beat Real Sociedad 1-0 thanks to a first-half goal by Junio Firpo.