Arsenal entered the match five points clear at the top of the table, aiming to extend their lead, but struggled at Villa Park as Aston Villa took control and opened the scoring in the first half.
A long cross found its way to Matty Cash, who slotted the ball past David Raya.
Mikel Arteta brought on Leandro Trossard, and the Belgian midfielder levelled for Arsenal.
But it was the hosts who got the winner with the very last kick of the game, following a scramble in the box.
The victory moves Aston Villa to 30 points, just three behind Arsenal, as they await the outcome of Manchester City’s clash with Sunderland at the Etihad.