Anthony Martial gave the hosts the lead just before half-time with a clinical header after a pin-point cross from Aaron Wan-Bissaka.
Bertrand Traore got Villa level with a tap-in at the back post which beat David de Gea.
The scoreline was not level for long as Paul Pogba was brought down in the box clumsily by Douglas Luiz. Bruno Fernandes stepped up to the spot and calmly executed the penalty to retake the lead.
Story of the game
United started the game with high press and direct football, which is something their manager, Ole Gunnar Solskjaer has wanted to implement into his side over the past month.
Martial had a typical curling effort of his in the early stages which was the first save of many by Emiliano Martinez. Villa went up the other end with Matty Cash who put a deep ball in for John McGinn to meet on the volley which forced De Gea to make the save.
In an end-to-end spell of play, United countered quickly where Marcus Rashford's strike rebounded of Tyrone Mings for Bruno Fernandes to lay it into Pogba who's shot was narrowly wide.
Fernandes was next to attempt a curling strike as he nearly chipped Martinez to give United the lead before half-time.
Martial then gave United the lead late in the opening 45 minutes as Wan-Bissaka went on a fine drive down the right wing and put the ball on a plate for Martial to head home. Martial's movement will have made Solskjaer proud, he got himself in between the two centre-halves and headed past Martinez with confidence - something the striker has been lacking of late.
Villa came out of the half-time break ready for battle and nearly had themselves level. Ollie Watkins' header required a De Gea save to keep the hosts ahead.
They then got their well deserved equaliser, Jack Grealish's low driven cross was met by Traore who smashed it past De Gea to make it 1-1.
United went straight back up the other end and Pogba was brought down in the box by Douglas Luiz. Michael Oliver rewarded United with the penalty and VAR agreed.
Who else other than Fernandes stepped up to the spot and perfectly placed the penalty to give United a 2-1 lead.
Pogba then had the winner on a plate for him as Luke Shaw drilled in a low cross for Pogba to smash into the bottom left corner from ten yards out but his shot was wide. He knew he should have scored and let out all frustration.
Fernandes then let rip from outside the box which Martinez tipped onto the bar and out for a corner, it would have been some goal. Martinez kept his side in the match.
What this means for both sides
Villa's unbeaten run of five matches in the league has come to an end and Dean Smith's side remain just three points off the top four with a game in hand.
As for Solskjaer and his men, they have extended their unbeaten run to six matches in the league and are level on points with league leaders Liverpool. They have both now played the same games, however, Liverpool play Southampton on Monday night.