Gomis latched onto Jefferson Montero’s cross with three minutes remaining after the Frenchman had missed a host of chances for the visitors.
The result leaves Villa three points above the relegation zone with eight games left.
Villa went into the game looking for a fourth straight win in all competitions, while Swansea, sitting pretty in mid-table, had lost their previous two.
But Swansea had most of the chances in the first half, the majority falling to Gomis.
The Frenchman forced a fine save from Brad Guzan after six minutes from six yards after being found by Neil Taylor, and the American had to be at his best again later in the half, blocking Gomis’ left-footed effort from 10 yards.
Guzan’s stops nearly counted for nothing just before the break when the Villa goalkeeper fumbled a Gylfi Sigurdsson cross, but Ciaran Clark cleared Wayne Routledge’s resulting effort off the line.
Lukasz Fabianski was tested just once in the opening 45 minutes, the Polish stopper doing well to keep out Fabian Delph’s driven effort from the angle.
Villa came out for the second-half the brighter, but Gabriel Agbonlahor’s effort on the swivel trickled wide of Swansea’s goal.
Swans boss Garry Monk brought winger Montero on with 25 minutes remaining, and the Ecuadorian instantly caused Leandro Bacuna problems down the right.
Montero’s cross found Gomis 12 yards out with 15 minutes remaining, but his goal-bound effort was superbly blocked by Clark.
However, it was Montero’s next delivery with the outside of his foot as Swansea broke that found Gomis six yards out, the striker poking home under Guzan for the winner.
Swansea nearly doubled their lead late on when Routledge broke free, but Guzan stood tall to keep it out.
Villa pressed in the closing stages with three corners, but Swansea held on to keep Villa rooted in a survival battle.
Charlie Nicholas’ verdict:
This was a very enjoyable game. I wasn’t expecting many goals and I certainly wasn’t expecting as many chances as were created by both sides. Swansea were excellent again in the first half.
Gomis in particular had three good opportunities. Guzan’s kicking wasn’t great today but his reactions were very, very good. Second half, Villa were much better. As every chance was falling to Gomis for Swansea, every chance was falling to Sinclair for Villa.
It was like a shootout between the two. It was Gomis who came up with it. The finish will get all the credit but set up play was fantastic, it was a beautiful crafted bit of play.
Aston Villa: Guzan (7), Hutton (5), Okore (6), Clark (6), Bacuna (4), Delph (7), Cleverley (6), N’Zogbia (6), Sinclair (6), Benteke (5), Agbonlahor (5)
Subs: Westwood (5), Weimann (5), Sanchez (5)
Swansea: Fabianski (6), Naughton (6), Fernandez (6), Williams (7), Taylor (7), Ki (7), Cork (5), Shelvey (6), Routledge (7), Sigurdsson (5), Gomis (7)
Subs: Oliveira (5), Dyer (5), Montero (7)
Man of the match: Jefferson Montero