The 16-year-old winger, making only his second start for the club, hit the woodwork twice and set up the opening goal for Gavi in an impressive performance which stood out amid a chaotic battle.
Veteran Polish striker Robert Lewandowski tapped home the winning goal, his first of the season, after Yamal’s drive hit the post, to send Barca provisionally third.
With coach Xavi watching on from high in the stands, serving a suspension, his charges took an early two-goal lead against the run of play.
Villarreal started brightly and Barcelona goalkeeper Marc-Andre ter Stegen did well to cut out Alexander Sorloth’s cut-back. The Norwegian forward also had a goal strike out for offside.
However Barcelona pounced after 12 minutes when Yamal crossed to the back post to find fellow academy graduate Gavi, who headed home.
Just three minutes later Frenkie de Jong rolled home the Catalans’ second. Alfonso Pedraza tackled Lewandowski but the ball rebounded kindly into the Dutch midfielder’s path and he finished calmly.
Barcelona were missing injured midfielder Pedri and left-back Alejandro Balde, and Villarreal soon hit back.
Juan Foyth’s produced a bullet header from Alex Baena’s corner to earn the hosts a foothold at the Estadio de la Ceramica — it was the first goal Barcelona have conceded this season.
The second soon followed with Sorloth tapping home Pedraza’s cross after a sublime pass by veteran forward Gerard Moreno helped create the chance.
Villarreal went ahead early in the second half after another impressive surge from Pedraza, who teed up Baena for a clinical finish.
Captain Sergi Roberto struggled badly at right back for Barcelona, who are close to signing Joao Cancelo from Manchester City on loan to occupy that position.
Barca winger Yamal crashed an effort against the crossbar as he frequently pried at Villarreal’s defence, looking to drag the visitors level.
Substitute Ferran Torres continued his strong pre-season form by pulling Barcelona level and soon Lewandowski put the champions ahead.
Yamal was heavily involved again, with his vicious drive tipped on to the post by Villarreal goalkeeper Filip Jorgensen, but Lewandowski was in the right place at the right time to turn home the rebound.
The Polish striker could have killed the game in stoppage time but fired at Jorgensen when through on goal, selfishly deciding not to pass to Ansu Fati, running alongside in support.
Yamal, playing in place of suspended winger Raphinha, did more than enough to give his coach Xavi a selection headache next weekend when the Brazilian returns.