Peter Crouch condemned Villa to a third consecutive defeat, taking advantage of a misunderstanding between keeper Brad Guzan and defender Chris Herd to fire home Stoke's winner.
Libor Kozak had raised hopes of a point at the Britannia Stadium with a 66th minute equaliser after sub Charlie Adam had put the Potters ahead early in the second half.
But four minutes after the Czech striker had punished a mistake by full-back Erik Pieters, Crouch pounced for a simple winner.
It was a massive disappointment for Paul Lambert's side, who will be looking to get back to winning ways against Crystal Palace on Boxing Day.
After a disjointed opening in which neither side were able to string more than a couple of passes together, Villa carved out the first chance in the 10th minute, Nathan Baker meeting Ashley Westwood's left-win cross with a diving header which was held by Asmir Begovic at the near post.
Almost immediately there was another opening as Kozak just failed to connect with Marc Albrighton's low cross from the other flank, although a linesman's flag was raised anyway.
Then Aleks Tonev produced a right-foot volley that was well held by Begovic, before Albrighton found himself in the wars.
The winger was clearly in discomfort after a strong challenge sent him sliding towards the advertising boards, and having picked himself up he was booked for a late tackle on Erik Pieters.
There was danger at the other end in the 23rd minute, Ciaran Clark heading clear after Oussama Assaidi had sprinted down the left to get in a fine cross.
But Stoke defender Wilson was lucky to escape a red card four minutes later when he sent Andi Weimann sprawling just outside the penalty area.
It looked a clear scoring opportunity but the ref deemed that a caution was sufficient and Westwood's free-kick cannoned off the home side's defensive wall for a corner.
It was the 37th minute before acting skipper Guzan had to make a save and even then it was from a cross, the keeper tipping over when Geoff Cameron's fine delivery from the right threatened to dip under the bar.
Cameron headed wide from the flag kick before the lively Albrighton made a surging run through the middle to send a low left-footer not far wide from just outside the penalty area.
But Clark came to the rescue in the 42nd minute, sliding in to block Crouch's low shot when the former Villa man looked a certain scorer from Assaidi's cross from the left.
The home side sent on Adam at the start of the second half, and five minutes after the break he broke the deadlock.
Cameron's free-kick from inside his own half was headed on by Crouch, and Adam turned away from Baker's challenge to send a low left-foot shot past Guzan from eight yards.
There was a chance for Villa to respond when Begovic's attempted punched clearance fell short.
Baker shaped up as if to shoot but then played the ball wide to Tonev, whose low angled drive flew across the face of goal and out for a throw-in on the far side of the pitch.
Weimann then flicked just wide of the near post following a low free-kick from Albrighton and the Austrian also had a fierce drive blocked by Wilson before Villa drew level.
Guzan's long kick was partially cleared by Ryan Shawcross but Pieters attempted to head it back to Begovic and Kozak nipped in to fire past the stranded keeper from close range.
If that was something of a gift, though, the visitors were equally benevolent on 70 minutes, Guzan and Chris Herd getting in a mix-up trying to deal with a Cameron cross and leaving Crouch the simple task of firing into an unguarded goal from a couple of yards.
It almost got worse three minutes later when Crouch flicked against the right-hand post from six yards, although Kozak almost produced a second equaliser with a rising shot on the turn that Begovic tipped over the bar.
Stoke City: Begovic; Cameron, Shawcross, Wilson, Pieters; Walters, Nzonzi, Arnautovic (Adam HT), Whelan, Assaidi (Pennant 72); Crouch. Unused subs: Sorensen, Miniesa, Palacios, Jones, Wilkinson.
Villa: Guzan; Lowton, Herd, Baker, Clark; Albrighton (Bacuna 81), Westwood, Delph, Tonev (Bowery 67); Kozak, Weimann. Unused subs: Steer, El Ahmadi, Helenius, Luna, Sylla.