The match was a crucial one for the Spanish giants, following a recent derby defeat to Atletico Madrid. They were looking to bounce back at the Bernabeu, a stadium where they have been nearly unbeatable in recent months.
The home team started strong, with Arda Guler firing an angled shot over the bar after a nice combination with Kylian Mbappe. Marcelino's Villarreal team was absorbing a lot of pressure, but they also had their chances, including a close call for Aurelien Tchouameni and Franco Mastantuono.
Villarreal had a brief moment of hope when Tani Oluwaseyi got a clear shot on goal, but Real Madrid's Thibaut Courtois made a quick save to deny the opportunity.
As the half drew to a close, Mastantuono had a chance to score, but his shot went just wide of the post.
Real Madrid finally broke the deadlock just two minutes into the second half when Vinicius Junior made a classic run down the left flank and shot, which took a deflection and flew past the Villarreal goalkeeper.
The hosts were awarded a penalty after Vinicius was fouled in the box, and he scored his fourth goal in as many league matches against Villarreal, making it 2-0.
Real Madrid continued to dominate, with Jude Bellingham having two chances in quick succession, but the Villarreal goalkeeper made a good save to deny him.
However, Villarreal pulled one back with a great strike from Georges Mikautadze, but their hopes of a comeback were dashed when Santiago Mourino received a second yellow card and was sent off.
Mbappe sealed the win for Real Madrid in the 81st minute, scoring his 14th goal in 10 appearances across all competitions, and the match was put to bed.
The win extended Real Madrid's unbeaten streak in this fixture to five games, while Villarreal saw their three-match winning streak come to an end.