It is the 12th title for the 26-year-old Serb and second seed but her first success since victory in Bali in 2011.
What started as a one-sided affair, with Ivanovic racing to a 5-1 lead in the first set, took two hours 19 minutes to complete as seven-times Grand Slam winner Williams fought her way back into the contest.
"It was very tough. Venus showed once again what a great sport she has been over the past years and I hope for many more years to come," said Ivanovic, a former French Open winner.
Williams acknowledged she had been beaten by the better player. "I just kept fighting, despite the odds. She was playing so well," she said.
In the tournament, which serves as a warm-up for this month's Australian Open, Williams faced championship point in the second set when serving at 30-40 and down 3-5 before her big serve kept her hopes alive.
She held serve then broke Ivanovic twice to send the final into a deciding third set.
It was only the second time in 10 attempts that Ivanovic has beaten the 33-year-old Williams, who has not won a title since October 2012.
