diff --git a/pyopencl/c_wrapper/wrap_cl_core.h b/pyopencl/c_wrapper/wrap_cl_core.h
index c00379997b106467cc66d5c7f6c0aa84e271f7f6..9d760492c91d9e69918165c35df645b7d691b75f 100644
--- a/pyopencl/c_wrapper/wrap_cl_core.h
+++ b/pyopencl/c_wrapper/wrap_cl_core.h
@@ -76,6 +76,8 @@ error *command_queue__flush(clobj_t queue);
 // Buffer
 error *create_buffer(clobj_t *buffer, clobj_t context, cl_mem_flags flags,
                      size_t size, void *hostbuf);
+error *buffer__get_sub_region(clobj_t *_sub_buf, clobj_t _buf, size_t orig,
+                              size_t size, cl_mem_flags flags);
 // Memory Object
 error *memory_object__release(clobj_t obj);
 // Memory Map
diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index 0017411996a02fdc86ea8d23e2263bfc6a080164..d9cf40c2db5d911e70ce7b565ca157566ffc087d 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -720,6 +720,14 @@ class Buffer(MemoryObject):
             ptr_buffer, context.ptr, flags, size, c_hostbuf))
         self.ptr = ptr_buffer[0]
 
+    def get_sub_region(self, origin, size, flags=0):
+        _sub_buf = _ffi.new('clobj_t*')
+        _handle_error(_lib.buffer__get_sub_region(_sub_buf, self.ptr, orig,
+                                                  size, flags))
+        sub_buf = self._create(_sub_buf[0])
+        MemoryObject.__init__(sub_buf, None)
+        sub_buf._handle_buf_flags(flags)
+
     # TODO __getitem__ ?
 
 # }}}
@@ -867,7 +875,6 @@ class NannyEvent(Event):
 #   UserEvent
 #   enqueue_migrate_mem_objects
 #   enqueue_migrate_mem_objects_ext
-#   create_sub_buffer
 
 # }}}
 
diff --git a/src/c_wrapper/buffer.cpp b/src/c_wrapper/buffer.cpp
index b0775d65faa56d19aa5b4cb4cb9fb2a1f24c3e69..36d10bb0b215d8624d5607ea95dce2904e9fb09f 100644
--- a/src/c_wrapper/buffer.cpp
+++ b/src/c_wrapper/buffer.cpp
@@ -151,10 +151,10 @@ enqueue_fill_buffer(clobj_t *evt, clobj_t _queue, clobj_t _mem, void *pattern,
         });
 }
 
-// {{{ rectangular transfers
-
 #if PYOPENCL_CL_VERSION >= 0x1010
 
+// {{{ rectangular transfers
+
 error*
 enqueue_read_buffer_rect(clobj_t *evt, clobj_t _queue, clobj_t _mem, void *buf,
                          const size_t *_buf_orig, size_t buf_orig_l,
@@ -233,5 +233,16 @@ enqueue_copy_buffer_rect(clobj_t *evt, clobj_t _queue, clobj_t _src,
         });
 }
 
-#endif
 // }}}
+
+error*
+buffer__get_sub_region(clobj_t *_sub_buf, clobj_t _buf, size_t orig,
+                       size_t size, cl_mem_flags flags)
+{
+    auto buf = static_cast<buffer*>(_buf);
+    return c_handle_error([&] {
+            *_sub_buf = buf->get_sub_region(orig, size, flags);
+        });
+}
+
+#endif