Carles Alena then doubled Barcelona's advantage in the 87th minute as the Spanish champions moved ahead of Sevilla to the top of the table.
The pace of Samuel Chukwueze was a key feature of Villarreal's work inside the first five minutes, with the 19-year-old having the chance to turn on the speed on more than one occasion.
Barcelona's first attempt of the match arrived in the ninth minute when Lionel Messi looked to pick out the bottom corner from outside the box, but Villarreal goalkeeper Sergio Asenjo made a smart save.
Villarreal almost took the lead in the 14th minute when the ball broke kindly for Gerard Moreno inside the home side's box, but the striker smashed the post.
Ivan Rakitic then just missed the goal with an effort down the other end during an open period of the match.
Asenjo kept out a Messi free kick in the 28th minute as opportunities continued to arrive, with Dembele also having a goal-bound strike blocked 15 minutes before the end of the first period.
Barcelona did make the breakthrough in the 36th minute, however, when Pique headed a pin-point Dembele cross into the back of the net from close range.
Messi came close to doubling the home side's advantage in the 38th minute, but Asenjo, who might feel that he should have done better with Pique's header, was on hand to deny the Argentine with a very smart save.
Asenjo made another excellent save to keep out a curling Messi effort early in the second period, before the Villarreal goalkeeper kept out a Rakitic effort from a Dembele cross.
The score was still 1-0 Barcelona entering the final 25 minutes of action, with Villarreal staying in the match without really threatening to level the scores.
Malcom headed just over the crossbar in the 83rd minute as Barcelona threatened a second, and it finally arrived in the 87th minute when 20-year-old midfielder Alena ran onto a pass from Messi before lifting an excellent finish over Asenjo.
BARCELONA (4-3-3): Ter Stegen; Semedo, Pique, Lenglet, Alba; Rakitic, Vidal (Alena 71'), Busquets; Dembele, Messi, Coutinho (Malcom 80')
VILLARREAL (4-4-2): Asensjo; Gaspar, Alvaro, Ruiz, Pedraza; Cazorla (Raba 88'), Caseres, Trigueros (Bacca 67'), Fornals; Moreno (Ekambi 79'), Chukwueze