Well - to detect the RPM, the simplest way would be to use a phototransistor/ir led slot detector pair, and a disk on the motor shaft with a hole in it that passes thru the slot. So - every pulse you sense is one revolution of the motor. Hook this up to a pin on the Arduino and use a pin-change interrupt function to update a variable based on a timed value (so you know how long it was from one event to the next); I am not sure if this will be a problem or not, or if there will be jitter due to the timer interfering with the interrupt (or vice-versa) - but that's the basic idea.
So now, in your main code, you'll have a variable that you can access (updated in the ISR) - that contains a value that approximates the RPM; actually, how long it takes for the shaft to rotate once. Convert this value to an RPM (don't do this in the ISR!). Then, compare your "set-point" RPM to this RPM; if the read value from the ISR is lower (caused by a load or other) than your set-point RPM, increase the PWM by some amount, if the value read is higher (lack of load or other), decrease it by some amount. You may or may not need to have a "window percentage" value for your comparison, to avoid oscillation.
That's the basics - I think (I've never done this - but it seems reasonable). You might want to look at PID control further, though; depending on how accurate you need it, PID might give you better accuracy, and help to prevent oscillation as well (once tuned). Note that I don't think you'll ever get "perfect" RPM timing. Something you might try, though, to increase accuracy, is to add more "slots" or "holes" to the timing disc.
One other thing: Depending on your skill, you might be able to eliminate the timing disc and detector entirely, by detecting the back-emf field "spike", which should correlate with the RPM of the motor (something to think about).
Good luck - hope this helps, or at least gives you some direction!