Muguruza beat her fellow former world No.1 3-6 6-3 6-4 after two hours and 19 minutes, having been one point away from falling 5-3 down in an entertaining decider at Foro Italico.
The 2016 French Open winner managed to hold her serve on that occasion, then broke to love in the next game before going on to seal the match at the third attempt.
"I think it was a tough match. I knew it was going to be a tough match. She's a good player, she's playing good, she's with a lot of confidence," Muguruza said.
"I knew it was going to be a tough battle. I was ready for it. I stood behind her and was waiting for my opportunities. She was playing great at the beginning. She took the first set. I kept myself together and said, 'Okay, let's start another battle in the second set'."
Next up for Muguruza is two-time Rome finalist Halep, who saw Yulia Putintseva retire from their quarter-final meeting because of a lower back injury.
After dropping her serve to fall 6-2 2-0 down to the world No.2 in 47 minutes, Putintseva, who played back-to-back three-set matches in the previous two rounds, pulled out of the match.
Halep said of Muguruza: "Every time I played well against her, [I was] as much as possible aggressive. If I play my best game and if I feel great physically on court, I have a big chance to win the match. But every time is different, because she's playing so hard.
"You don't really know what to expect. It's tough every time. So I don't plan for a specific match, because you never know on court."
Two-time Internazionali d'Italia champion Elina Svitolina was comprehensively beaten 6-3 6-0 by Marketa Vondrousova, who was the runner-up at last year's French Open.
Standing between Vondrousova and her first final appearance since Roland Garros last year is reigning champion Karolina Pliskova.
No.2 seed Pliskova overcame Elise Mertens 6-3 3-6 6-0 as she continued to impress after initially struggling when the WTA Tour returned in August.