diff --git a/gobject/valaccodeassignmentmodule.vala b/gobject/valaccodeassignmentmodule.vala
index 56abf3e..6e1eca3 100644
--- a/gobject/valaccodeassignmentmodule.vala
+++ b/gobject/valaccodeassignmentmodule.vala
@@ -340,7 +340,28 @@ public class Vala.CCodeAssignmentModule : CCodeModule {
 			cop = CCodeAssignmentOperator.SHIFT_RIGHT;
 		}
 	
-		CCodeExpression codenode = new CCodeAssignment ((CCodeExpression) codegen.get_ccodenode (assignment.left), rhs, cop);
+		CCodeExpression codenode;
+
+		if (assignment.left.value_type.data_type != null
+		    && assignment.left.value_type.data_type.get_type_id () == "G_TYPE_VALUE"
+		    && assignment.right.value_type.data_type.get_set_value_function () != null) {
+			codegen.requires_value_init = true;
+
+			var ccall_init = new CCodeFunctionCall (new CCodeIdentifier ("VALA_VALUE_INIT"));
+			ccall_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, (CCodeExpression) codegen.get_ccodenode (assignment.left)));
+			ccall_init.add_argument (new CCodeConstant (assignment.right.value_type.data_type.get_type_id ()));
+
+			var ccall_set = new CCodeFunctionCall (new CCodeIdentifier (assignment.right.value_type.data_type.get_set_value_function ()));
+			ccall_set.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, (CCodeExpression) codegen.get_ccodenode (assignment.left)));
+			ccall_set.add_argument ((CCodeExpression) codegen.get_ccodenode (assignment.right));
+
+			var ccomma = new CCodeCommaExpression ();
+			ccomma.append_expression (ccall_init);
+			ccomma.append_expression (ccall_set);
+			codenode = ccomma;
+		} else {
+			codenode = new CCodeAssignment ((CCodeExpression) codegen.get_ccodenode (assignment.left), rhs, cop);
+		}
 
 		if (unref_old && codegen.get_ccodenode (assignment.left) is CCodeElementAccess) {
 			// ensure that index expression in element access doesn't get evaluated more than once
diff --git a/gobject/valaccodebasemodule.vala b/gobject/valaccodebasemodule.vala
index 3dd4aba..11487e6 100644
--- a/gobject/valaccodebasemodule.vala
+++ b/gobject/valaccodebasemodule.vala
@@ -335,6 +335,9 @@ public class Vala.CCodeBaseModule : CCodeModule {
 		if (codegen.requires_strcmp0) {
 			append_vala_strcmp0 ();
 		}
+		if (codegen.requires_value_init) {
+			codegen.source_type_declaration.append (new CCodeMacroReplacement ("VALA_VALUE_INIT(v,t)", "(!G_IS_VALUE (v) ? g_value_init (v, t) : (G_VALUE_TYPE (v) != t ? (g_value_unset (v), g_value_init (v,t)) : NULL))"));
+		}
 		
 		if (codegen.string_h_needed) {
 			codegen.source_include_directives.append (new CCodeIncludeDirective ("string.h"));
diff --git a/gobject/valaccodegenerator.vala b/gobject/valaccodegenerator.vala
index be6b3cd..be1c885 100644
--- a/gobject/valaccodegenerator.vala
+++ b/gobject/valaccodegenerator.vala
@@ -110,6 +110,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
 	public DataType double_type;
 	public TypeSymbol gtype_type;
 	public TypeSymbol gobject_type;
+	public DataType gvalue_type;
 	public ErrorType gerror_type;
 	public Class glist_type;
 	public Class gslist_type;
@@ -136,6 +137,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
 	public bool requires_array_free;
 	public bool requires_array_move;
 	public bool requires_strcmp0;
+	public bool requires_value_init;
 	public bool dbus_glib_h_needed;
 
 	public Set<string> wrappers;
@@ -256,6 +258,7 @@ public class Vala.CCodeGenerator : CodeGenerator {
 
 		gtype_type = (TypeSymbol) glib_ns.scope.lookup ("Type");
 		gobject_type = (TypeSymbol) glib_ns.scope.lookup ("Object");
+		gvalue_type = new ValueType ((TypeSymbol) glib_ns.scope.lookup ("Value"));
 		gerror_type = new ErrorType (null, null);
 		glist_type = (Class) glib_ns.scope.lookup ("List");
 		gslist_type = (Class) glib_ns.scope.lookup ("SList");
@@ -3515,9 +3518,24 @@ public class Vala.CCodeGenerator : CodeGenerator {
 					// (tmp = expr, &tmp)
 					var ccomma = new CCodeCommaExpression ();
 
-					var temp_var = get_temp_variable (arg.value_type);
+					var temp_var = get_temp_variable (param.parameter_type);
+
 					temp_vars.insert (0, temp_var);
-					ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (temp_var.name), cexpr));
+
+					//implicit conversion to GValue
+					if (param.parameter_type.get_type_id () == "G_TYPE_VALUE" && arg.value_type.data_type.get_set_value_function () != null) {
+						var ccall_init = new CCodeFunctionCall (new CCodeIdentifier ("VALA_VALUE_INIT"));
+						ccall_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_var.name)));
+						ccall_init.add_argument (new CCodeConstant (arg.value_type.get_type_id ()));
+						ccomma.append_expression (ccall_init);
+
+						var ccall_set = new CCodeFunctionCall (new CCodeIdentifier (arg.value_type.data_type.get_set_value_function ()));
+						ccall_set.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_var.name)));
+						ccall_set.add_argument (cexpr);
+						ccomma.append_expression (ccall_set);
+					} else {
+						ccomma.append_expression (new CCodeAssignment (new CCodeIdentifier (temp_var.name), cexpr));
+					}
 					ccomma.append_expression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_var.name)));
 
 					return ccomma;
@@ -3592,7 +3610,15 @@ public class Vala.CCodeGenerator : CodeGenerator {
 				Report.error (expr.source_reference, "Operation not supported for this type");
 				return;
 			}
-			expr.ccodenode = new CCodeCastExpression ((CCodeExpression) expr.inner.ccodenode, expr.type_reference.get_cname ());
+			if (expr.inner.value_type.data_type != null
+			    && expr.inner.value_type.data_type.get_type_id () == "G_TYPE_VALUE"
+			    && expr.type_reference.data_type.get_get_value_function () != null) {
+				var ccall = new CCodeFunctionCall (new CCodeIdentifier (expr.type_reference.data_type.get_get_value_function ()));
+				ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, (CCodeExpression) expr.inner.ccodenode));
+				expr.ccodenode = ccall;
+			} else {
+				expr.ccodenode = new CCodeCastExpression ((CCodeExpression) expr.inner.ccodenode, expr.type_reference.get_cname ());
+			}
 		}
 	}
 	
diff --git a/vala/valadatatype.vala b/vala/valadatatype.vala
index a3c2144..89278be 100644
--- a/vala/valadatatype.vala
+++ b/vala/valadatatype.vala
@@ -354,6 +354,11 @@ public abstract class Vala.DataType : CodeNode {
 			return true;
 		}
 
+		if (target_type.get_type_id () == "G_TYPE_VALUE"
+		    && this.data_type.get_set_value_function () != null) {
+			return true;
+		}
+
 		return false;
 	}
 
