Robert Lewandowski’s goal sealed the win for Barca, three minutes after Ferran Torres’ equaliser.
Villarreal came back from 2-0 down to lead 3-2 after 50 minutes, with goals from Juan Foyth, Alexander Sorloth and Alex Baena.
Barca had raced into an early lead after 15 minutes when Gavi and Frenkie de Jong scored for the visitors.
Gavi headed in from a Lamine Yamal cross before De Jong got on the end of a Lewandowski backheel in the box.
Yamal’s assist saw him become the youngest player to assist a goal in a La Liga game in the 21st century, aged 16 years and 45 days.
Foyth headed home from Baena’s corner before Sorloth equalised following an excellent team move by the Yellow Submarine.
Baena got on the scoresheet early in the second half, curling past Marc-Andre ter Stegen.
Villarreal were then pegged back as Torres scored Barcelona’s equaliser from close range, before Lewandowski’s finish from close range secured the three points for Barca from a dramatic contest.
Xavi’s side are now third with three games played, two points behind leaders Real Madrid.
𝗦𝗲𝗺𝗮𝘀𝗼𝗰𝗶𝗮𝗹 𝗶𝘀 𝘄𝗵𝗲𝗿𝗲 𝗿𝗲𝗮𝗹 𝗽𝗲𝗼𝗽𝗹𝗲 𝗰𝗼𝗻𝗻𝗲𝗰𝘁, 𝗴𝗿𝗼𝘄, 𝗮𝗻𝗱 𝗯𝗲𝗹𝗼𝗻𝗴. We’re more than just a social platform — from jobs and blogs to events and daily chats, we bring people and ideas together in one simple, meaningful space.