There is no "wrapping" in a struct going on here. For all practical purposes, System.Int32 struct is a built-in primitive type, in the sense that the compiler recognizes them, and generates special instructions while handling expressions of primitive types. The only place where an int (or any other struct for that matter) is wrapped is during a boxing conversion, which is required when you want to pass an int to an API that takes an object.
The biggest difference between Java's and C#'s handling of primitives is that you can use C# primitives in places where user-defined struct types can go, most notably, in C# generic arguments, while Java treats primitives as a completely separate group of types.