Jens Lehmann saved Juan Roman Riquelme's last-minute penalty to send Arsenal into the Champions League final at Villarreal's expense.
Lehmann was mobbed by his team-mates at the final whistle
Villarreal looked set to send the game into extra-time when Gael Clichy fouled Jose Mari, but Lehmann dived to his left to save Riquelme's spot-kick.
Arsenal survived a siege, with Lehmann saving well from Guillermo Franco.
Diego Forlan also missed a glorious chance as Arsenal sealed a final clash with AC Milan or Barcelona in Paris.
Arsenal had to ride their luck and mount a rearguard action to reach the final on 17 May as the gifted Spanish outfit dominated throughout.
Sol Campbell, as expected, was recalled in place of the injured Philippe Senderos, for his first Champions League appearance since November.
Arsenal suffered an early blow when Mathieu Flamini limped off with a hamstring injury, to be replaced by Clichy, playing his first competitive game since November.
And he was on the defensive, along with his Arsenal colleagues, as Villarreal exerted total supremacy in the first 45 minutes.
Riquelme and Marcos Senna combined to set up Juan Pablo Sorin in the 17th minute, but he shot straight at Lehmann.
And five minutes before the interval, Lehmann came to Arsenal's rescue with a fine save from Franco's diving header as he closed on Javi Venta's fiercely-driven cross.
Villarreal ended the half in the ascendancy, with Lehmann clutching Riquelme's free-kick.
The second half started in bizarre fashion, when a fan raced on to the pitch and attempted to drape a Barcelona shirt over Thierry Henry before he was bundled away.
Lehmann dives to his left to keep out Riquelme's penalty
Franco almost broke the deadlock two minutes after the interval, with his powerful header flashing only inches wide with Lehmann well beaten.
The striker was dominating in the air, and once again he was only narrowly off target when he beat Campbell to Senna's cross.
Arsenal were living on their nerves, and they had another narrow escape after 64 minutes when Forlan shot wide of a gaping goal after a slick link-up with Franco.
Franco then had the ball in the net three minutes later, but his powerful strike was ruled out for offside.
Arsenal desperately needed to gain some momentum, and Wenger made a change after 68 minutes, sending on Robert Pires for Jose Antonio Reyes.
Just as time appeared to be running out, Villarreal were handed a lifeline as Clichy was harshly judged to have fouled Jose Mari in the area - but Lehmann won his battle with Riquelme to send Arsenal to Paris.
Villarreal: Barbosa, Javi Venta, Pena, Quique Alvarez, Arruabarrena (Roger 82), Riquelme, Josico (Jose Mari 63), Senna, Sorin, Forlan, Franco.
Subs Not Used: Viera, Arzo, Guayre, Hector Font, Rubio.
Arsenal: Lehmann, Eboue, Toure, Campbell, Flamini (Clichy 9), Hleb, Fabregas, Silva, Ljungberg, Reyes (Pires 69), Henry.
Subs Not Used: Almunia, Diaby, Van Persie, Song Billong, Djourou.
Ref: Ivan Ivanov (Russia).