diff --git a/configure.ac b/configure.ac
index 33f30e9..e3c065e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -33,6 +33,8 @@ CPPFLAGS+="${PYTHON_INCLUDES}"
 AC_CHECK_HEADER(Python.h, , AC_MSG_ERROR(Python headers not found))
 CPPFLAGS="${save_CPPFLAGS}"
 
+#libffi
+PKG_CHECK_MODULES(FFI, libffi >= 3.0)
 
 # GNOME
 PKG_CHECK_MODULES(GNOME,
diff --git a/gi/Makefile.am b/gi/Makefile.am
index bda8a34..970f81a 100644
--- a/gi/Makefile.am
+++ b/gi/Makefile.am
@@ -16,7 +16,9 @@ pygi_PYTHON = \
 
 _gi_la_CFLAGS = \
 	$(PYTHON_INCLUDES) \
-	$(GNOME_CFLAGS)
+	$(GNOME_CFLAGS) \
+        $(FFI_CFLAGS)
+      
 _gi_la_LDFLAGS = \
 	-module \
 	-avoid-version \
@@ -36,6 +38,8 @@ _gi_la_SOURCES = \
 	pygi-type.h \
 	pygi-boxed.c \
 	pygi-boxed.h \
+	pygi-closure.c \
+	pygi-closure.h \
 	pygi.h \
 	pygi-private.h \
 	pygobject-external.h \
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index edbb31f..f0373cb 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -372,8 +372,11 @@ check_number_release:
 
             switch (info_type) {
                 case GI_INFO_TYPE_CALLBACK:
-                    /* TODO */
-                    PyErr_SetString(PyExc_NotImplementedError, "callback marshalling is not supported yet");
+                    if (!PyCallable_Check(object)) {
+                        PyErr_Format(PyExc_TypeError, "Must be callable, not %s",
+                                object->ob_type->tp_name);
+                        retval = 0;
+                    }
                     break;
                 case GI_INFO_TYPE_ENUM:
                     retval = _pygi_g_registered_type_info_check_object(
@@ -875,9 +878,11 @@ array_item_error:
 
             switch (info_type) {
                 case GI_INFO_TYPE_CALLBACK:
-                    PyErr_SetString(PyExc_NotImplementedError, "callback marshalling is not supported yet");
-                    /* TODO */
-                    break;
+		    {						
+			arg.v_pointer = _pygi_make_native_closure((GICallableInfo*)info,
+								  object);
+			break;
+		    }
                 case GI_INFO_TYPE_BOXED:
                 case GI_INFO_TYPE_STRUCT:
                 {
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
new file mode 100644
index 0000000..d7da472
--- /dev/null
+++ b/gi/pygi-closure.c
@@ -0,0 +1,104 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ *   pygi-closure.c: PyGI Native C Closure functions
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#include "pygi-private.h"
+
+#include <string.h>
+#include <time.h>
+
+#include <datetime.h>
+#include <pygobject.h>
+
+void _pygi_handle_closure(ffi_cif *cif, void *result, void **args, void *userdata)
+{
+    PyGILState_STATE gstate;
+    PyGINativeClosure *closure = userdata;
+    gint n_args;
+    GITypeTag return_tag;
+    GITypeInfo *return_type;
+    GITransfer return_transfer;
+    GArgument  return_arg;
+    PyObject *retval;
+    PyObject *pyargs;
+
+    /* Lock the GIL as we are coming into this code without the lock and we
+      may be executing python code */
+    gstate = PyGILState_Ensure ();
+
+    n_args = g_callable_info_get_n_args (closure->info);
+    if (n_args > 0) {
+        PyErr_SetString(PyExc_TypeError,
+			"No support for callbacks with arguments yet.");
+        goto end;
+    }
+  
+    return_type = g_callable_info_get_return_type (closure->info);
+
+    if (return_type != GI_TYPE_TAG_VOID) {
+        PyErr_SetString(PyExc_TypeError, 
+			"No support for return values from callbacks yet.");
+        goto end;
+    }
+
+    return_tag = g_type_info_get_tag (return_type);
+    return_transfer = g_callable_info_get_caller_owns(closure->info);
+  
+    pyargs = PyTuple_New(n_args);
+
+    if (pyargs == NULL) {
+        goto end;
+    }
+
+    retval = PyObject_CallObject((PyObject *)closure->function, pyargs);
+    Py_DECREF(pyargs);
+
+end:
+    PyGILState_Release (gstate);
+}
+
+
+gpointer
+_pygi_make_native_closure (GICallableInfo* info,
+			   PyObject *function)
+{
+    /* Code copied with pythonic modifications from seed's make_native_closure() method */
+    ffi_cif *cif;
+    ffi_closure *fficlosure;
+    PyObject* cache;
+    PyObject* dict;
+    PyGINativeClosure *invoke_closure;
+
+    Py_INCREF(function);
+
+    cif = g_slice_new0(ffi_cif);
+
+    invoke_closure = g_slice_new0(PyGINativeClosure);
+    invoke_closure->info = (GICallableInfo *) g_base_info_ref ((GIBaseInfo *) info);  
+    invoke_closure->function = function;
+    invoke_closure->cif = cif;
+
+    fficlosure =
+        g_callable_info_prepare_closure (info, cif, _pygi_handle_closure,
+					 invoke_closure);
+    invoke_closure->closure = fficlosure;
+
+    return (gpointer) invoke_closure->closure;
+}
diff --git a/gi/pygi-closure.h b/gi/pygi-closure.h
new file mode 100644
index 0000000..da83325
--- /dev/null
+++ b/gi/pygi-closure.h
@@ -0,0 +1,49 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * vim: tabstop=4 shiftwidth=4 expandtab
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+#ifndef __PYGI_CLOSURE_H__
+#define __PYGI_CLOSURE_H__
+
+#include <Python.h>
+#include <girffi.h>
+#include <ffi.h>
+
+G_BEGIN_DECLS
+
+
+/* Private */
+
+typedef struct _PyGiNativeClosure
+{
+    GICallableInfo *info;
+    PyObject *function;
+    
+    ffi_closure *closure;
+    ffi_cif *cif;
+} PyGINativeClosure;
+
+
+
+void _pygi_handle_closure(ffi_cif *cif, void *result, void 
+			  **args, void *userdata);
+
+gpointer
+_pygi_make_native_closure (GICallableInfo* info,
+			   PyObject *function);
+#endif
diff --git a/gi/pygi-private.h b/gi/pygi-private.h
index 07ea385..7ad0321 100644
--- a/gi/pygi-private.h
+++ b/gi/pygi-private.h
@@ -24,6 +24,7 @@
 #include "pygi-boxed.h"
 #include "pygi-argument.h"
 #include "pygi-type.h"
+#include "pygi-closure.h"
 
 G_BEGIN_DECLS
 
