Of course they're necessary but they're not intrinsically evil, they're just done badly.
The basics of a good estimate:
1) Developers, ideally the ones who will do the work, have to be involved in generating them.
2) An estimate is a range (usually best case, worst case, most likely case), not a single value. You may use the range to approximate a single value ((best case + 4* most likely case + 2 * worst case) / 7 being a fair formula for doing so) but never forget that that's all it is - an approximation.
3) In my experience the most common reason for bad estimates is wishful thinking, either on the part of the developer (who is optimistic it will all go fine) or the manager (who is desparate for it all to go quickly). This needs to be fought - any estimate based on everything going well is pretty much a cert to be massively under. Most likely case should probably assume that a certain amount of stuff isn't going to go the way you want it to.
4) In my experience the second most common reason for bad estimates is not thinking through everything that has to be done. It's not just the coding, it's the unit testing, the admin, the user guide, the back end maintenance screens relating to the functionality. Break down the task into individual components each taking between quarter of a day and five days - that sort of size can be estimated with a reasonable level of accuracy.
5) Measure the actual time things took and review afterwards and use that to improve estimates. Refer to actuals for similar previous tasks as a bench mark and to justify why things are higher than might be expected.
6) Estimate both at the micro level (each individual task) and the macro level (gut feel on how long the whole thing should take). Usually the macro level estimate will be lower - this is an indication that you might want to review (but not necessarily change) the micro level estimates. The sweet spot in my experience is when they either agree or, more likely, the macro level estimate is still lower but no one is willing to change any of the individual task estimates. At that point you use the individual task estimates.
7) Don't confuse the estimate and the commercial aspects. If you estimate 100 days and the usual charge out rate is $1,000 per day that should obviously be $100,000. If they say they can't charge that and win the business that's fine but (unless the scope changes) the estimate doesn't change, the charge out rate does.
8) Developers should be challenged on their estimates (as in asked to explain why something takes that long) but not pressured to lower them. Certainly not just because the numbers aren't what someone wants in any case - if they can't justify them then they usually need to be pushed for a better breakdown and potentially a second set of eyes but in a non-confrontational manner - remind the PM (or if you are the PM remember) that they're going to look bad if the project isn't delivered on time too so they should be keen that the estimates are solid.
9) Contingency should be added both shit happens contingency (usually 10 - 20%) and to cover specific risks. Contingency should be planned in but is "owned" by the project manager - that is if a developer needs to go into it he has to speak to the PM and say why he's over run his estimate. This usually helps stop the just filling time and keeps contingency for genuine stuff. If anyone objects to your shit happens contingency budget then explain it's just the reality of IT projects - stuff happens you can't predict. If they still don't like it then remember to hide it inside the estimates next time.
10) (Edit) Don't confuse effort and elapsed time. Effort is the total time that will need to be spent doing something, elapsed is the difference between when it starts and when it ends. They're normally different - admin, support, mentoring and life mean that the chances are that you won't get 5 days effort completed in a working week. Take 4 as a rough guide but adjust according to the company and the other commitments of the team members.
11) (Edit - from Martin Wickman) Other work you've done or are planning can be a valuable source of information when estimating. In the comments below Martin refers to Relative Estimating which involves comparing like tasks with each other to ensure that the estimates assigned seem in proportion given the work involved. It's surprising how often you'll happily assign 1 week to one task and 1 week to another but when you look at the two things one is clearly more complex than the other - that's a good indication that one (or both) figures are wrong. Taking this further you get into evidence based scheduling which uses completed tasks and projects as a key input into estimates for future work - at a very basic level "how long did it take last time we did something like this?"
Steve McConnell wrote about all of this in Software Estimation. It's a bit dry but it's very thorough on the subject.