I can second GeoNames. Sometimes it's hard to beat free. We take a couple files from their dump[1] (primarily the city data) and import into a database. We can then geolocate a lat/long to the closest city.
I'm using it for a photo app (I only need town/city level granularity), and it works well for my needs. Note that the dataset is based upon populated places though, so YMMV if you need to lookup somewhere in the middle of nowhere.
Here is a JavaScript library I wrote for it, along with some scripts for munging the GeoNames dataset: