diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index a87871c..32e9dfe 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -150,9 +150,8 @@ internal class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
 
 				if (f.access == SymbolAccessibility.PRIVATE) {
 					var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname ())));
-					var ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
-					ccall2.add_argument (cast);
-					ccall.add_argument (ccall2);
+					ccall.add_argument (klass);
+					ccall.add_argument (new CCodeIdentifier ("%s".printf (cl.get_type_id ())));
 					expr.ccodenode = new CCodeMemberAccess.pointer (ccall, f.get_cname ());
 				} else {
 					expr.ccodenode = new CCodeMemberAccess.pointer (cast, f.get_cname ());
diff --git a/codegen/valaclassregisterfunction.vala b/codegen/valaclassregisterfunction.vala
index 1e299e7..ad7ec12 100644
--- a/codegen/valaclassregisterfunction.vala
+++ b/codegen/valaclassregisterfunction.vala
@@ -51,7 +51,7 @@ public class Vala.ClassRegisterFunction : TypeRegisterFunction {
 	}
 
 	public override string get_base_init_func_name () {
-		if (class_reference.class_constructor != null || class_reference.has_class_private_fields) {
+		if (class_reference.class_constructor != null || (!context.require_glib_version (2, 22) && class_reference.has_class_private_fields)) {
 			return "%s_base_init".printf (class_reference.get_lower_case_cname (null));
 		} else {
 			return "NULL";
@@ -67,7 +67,7 @@ public class Vala.ClassRegisterFunction : TypeRegisterFunction {
 	}
 
 	public override string get_base_finalize_func_name () {
-		if (class_reference.class_destructor != null || class_reference.has_class_private_fields) {
+		if (class_reference.class_destructor != null || (!context.require_glib_version (2, 22) && class_reference.has_class_private_fields)) {
 			return "%s_base_finalize".printf (class_reference.get_lower_case_cname (null));
 		} else {
 			return "NULL";
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 229c7bf..d8b30e2 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -421,10 +421,12 @@ internal class Vala.GTypeModule : GErrorModule {
 		if (is_gtypeinstance) {
 			if (cl.has_class_private_fields || has_class_locks) {
 				decl_space.add_type_declaration (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sClassPrivate".printf (cl.get_cname ()))));
-				var cdecl = new CCodeDeclaration ("GQuark");
-				cdecl.add_declarator (new CCodeVariableDeclarator ("_vala_%s_class_private_quark".printf (cl.get_lower_case_cname ()), new CCodeConstant ("0")));
-				cdecl.modifiers = CCodeModifiers.STATIC;
-				decl_space.add_type_declaration (cdecl);
+				if (!context.require_glib_version (2, 22)) {
+					var cdecl = new CCodeDeclaration ("GQuark");
+					cdecl.add_declarator (new CCodeVariableDeclarator ("_vala_%s_class_private_quark".printf (cl.get_lower_case_cname ()), new CCodeConstant ("0")));
+					cdecl.modifiers = CCodeModifiers.STATIC;
+					decl_space.add_type_declaration (cdecl);
+				}
 			}
 
 			/* only add the *Private struct if it is not empty, i.e. we actually have private data */
@@ -437,8 +439,12 @@ internal class Vala.GTypeModule : GErrorModule {
 			if (cl.has_class_private_fields || has_class_locks) {
 				decl_space.add_type_member_declaration (type_priv_struct);
 
-				var macro = "((%sClassPrivate *) g_type_get_qdata (type, _vala_%s_class_private_quark))".printf (cl.get_cname(), cl.get_lower_case_cname ());
-				decl_space.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_CLASS_PRIVATE(type)".printf (cl.get_upper_case_cname (null)), macro));
+				string macro;
+				if (context.require_glib_version (2, 22))
+					macro = "(G_TYPE_CLASS_GET_PRIVATE (klass, type, %sClassPrivate))".printf (cl.get_cname());
+				else
+					macro = "((%sClassPrivate *) g_type_get_qdata (G_TYPE_FROM_CLASS (klass), _vala_%s_class_private_quark))".printf (cl.get_cname(), cl.get_lower_case_cname ());
+				decl_space.add_type_member_declaration (new CCodeMacroReplacement ("%s_GET_CLASS_PRIVATE(klass, type)".printf (cl.get_upper_case_cname (null)), macro));
 			}
 			decl_space.add_type_member_declaration (prop_enum);
 		} else {
@@ -526,12 +532,12 @@ internal class Vala.GTypeModule : GErrorModule {
 			}
 
 
-			if (cl.class_constructor != null || cl.has_class_private_fields) {
+			if (cl.class_constructor != null || (!context.require_glib_version (2, 22) && cl.has_class_private_fields)) {
 				add_base_init_function (cl);
 			}
 			add_class_init_function (cl);
 
-			if (cl.class_destructor != null || cl.has_class_private_fields) {
+			if (cl.class_destructor != null || (!context.require_glib_version (2, 22) && cl.has_class_private_fields)) {
 				add_base_finalize_function (cl);
 			}
 
@@ -1020,7 +1026,7 @@ internal class Vala.GTypeModule : GErrorModule {
 		var init_block = new CCodeBlock ();
 		base_init.block = init_block;
 
-		if (cl.has_class_private_fields) {
+		if (!context.require_glib_version (2, 22) && cl.has_class_private_fields) {
 			var block = new CCodeBlock ();
 			var cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
 			cdecl.add_declarator (new CCodeVariableDeclarator ("priv"));
@@ -1040,6 +1046,9 @@ internal class Vala.GTypeModule : GErrorModule {
 
 			var iftrue = new CCodeBlock ();
 			ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname (null))));
+			ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_peek"));
+			ccall2.add_argument (new CCodeIdentifier ("parent_type"));
+			ccall.add_argument (ccall2);
 			ccall.add_argument (new CCodeIdentifier ("parent_type"));
 			iftrue.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("parent_priv"), ccall)));
 			block.add_statement (new CCodeIfStatement (new CCodeIdentifier ("parent_type"), iftrue));
@@ -1077,6 +1086,7 @@ internal class Vala.GTypeModule : GErrorModule {
 
 			ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname (null))));
 			ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
+			ccall.add_argument (new CCodeConstant ("klass"));
 			ccall2.add_argument (new CCodeIdentifier ("klass"));
 			ccall.add_argument (ccall2);
 			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("priv"), ccall)));
@@ -1193,9 +1203,8 @@ internal class Vala.GTypeModule : GErrorModule {
 
 			if (field.access == SymbolAccessibility.PRIVATE) {
 				ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS_PRIVATE".printf (cl.get_upper_case_cname ())));
-				var ccall2 = new CCodeFunctionCall (new CCodeIdentifier ("G_TYPE_FROM_CLASS"));
-				ccall2.add_argument (new CCodeIdentifier ("klass"));
-				ccall.add_argument (ccall2);
+				ccall.add_argument (new CCodeIdentifier ("klass"));
+				ccall.add_argument (new CCodeIdentifier ("%s".printf (cl.get_type_id ())));
 				left = new CCodeMemberAccess (ccall, field.get_cname (), true);
 			} else {
 				left = new CCodeMemberAccess (new CCodeIdentifier ("klass"), field.get_cname (), true);
diff --git a/codegen/valatyperegisterfunction.vala b/codegen/valatyperegisterfunction.vala
index 736883f..e48481e 100644
--- a/codegen/valatyperegisterfunction.vala
+++ b/codegen/valatyperegisterfunction.vala
@@ -120,7 +120,7 @@ public abstract class Vala.TypeRegisterFunction {
 
 		type_init.add_statement (get_type_interface_init_declaration ());
 
-		if (cl != null && cl.has_class_private_fields) {
+		if (cl != null && cl.has_class_private_fields && !context.require_glib_version (2, 22)) {
 			CCodeFunctionCall quark_reg_call;
 
 			if (plugin) {
@@ -168,6 +168,15 @@ public abstract class Vala.TypeRegisterFunction {
 		} else {
 			type_init.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (type_id_name), reg_call)));
 		}
+
+		 if (cl != null && cl.has_class_private_fields && context.require_glib_version (2, 22)) {
+			CCodeFunctionCall add_class_private_call;
+
+			add_class_private_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_add_class_private"));
+			add_class_private_call.add_argument (new CCodeIdentifier (type_id_name));
+			add_class_private_call.add_argument (new CCodeIdentifier ("sizeof (%sClassPrivate)".printf (get_type_declaration ().get_cname ())));
+			type_init.add_statement (new CCodeExpressionStatement (add_class_private_call));
+		}
 		
 		type_init.add_statement (get_type_interface_init_statements ());
 
