Real Madrid suffered only a second La Liga defeat this season as they missed the chance to return to the top of the table by losing to Villarreal.
Yeremy Pino gave the hosts the lead but a questionable assist off Juan Foyth allowed Karim Benzema to equalise.
Foyth then won his own penalty at the other end as David Alaba managed and Gerard Moreno netted the winner.
Real remain second, level on points with leaders Barcelona, who travel to Atletico Madrid on Sunday.
Villarreal climb to fifth after a deserved third straight win, having created the best chances throughout an entertaining Estadio de la Ceramica affair.
Alex Baena went close several times during a first half led by the hosts, while Francis Coquelin hit the post with a cheeky backheel from Moreno’s cross.
Benzema fashioned Real’s best first-half opener with a deflected first pass off Vinicius Jr’s volley, but the Brazilian striker was denied by veteran goalkeeper Pepe Reina.
Ferland Mendy’s misplaced pass led to Pino dismissing Villarreal early in the second half, but after an overhead ball grazed Foyth’s hand the referee awarded a penalty after seeing the fieldside monitor.
Benzema converted his 227th La Liga goal to rank sixth on the all-time top scorers list, alongside Real legend Alfredo di Stefano.
But any unfairness felt by the hosts quickly disappeared as Alaba slipped and handled Foyth’s low pass as he put his hand on the floor to steady himself, Moreno coldly sending Thibaut Courtois the wrong way after the Loud calls from Real finally died down.