This is partly due to the fact that PropertyInfo.SetValue predates generics - reflection has been part of .NET since the beginning.
However, using generics would be difficult in this specific case, in any manner. There is no way for the compiler to infer this information, as you suggested, since the property info is gleaned at run time, not compile time. That is the purpose behind Reflection.
Instead of trying to work this into a generic method (which would probably have to lead to a non-generic implementation, in any case, due to the runtime behavior), the CLR team made sure that all objects, including value types, work as a System.Object. Yes, this causes boxing, but with reflection's overhead, the small extra overhead of boxing a value type is not really worrisome.