diff --git a/pyopencl/c_wrapper/wrap_cl_core.h b/pyopencl/c_wrapper/wrap_cl_core.h
index 9f1d0d6d083a737174c6bdb7cc4082d96ccf95c5..458f6c3ace0a90cdc12383bb008503b610e21d7c 100644
--- a/pyopencl/c_wrapper/wrap_cl_core.h
+++ b/pyopencl/c_wrapper/wrap_cl_core.h
@@ -84,6 +84,9 @@ error *_enqueue_write_buffer(void **ptr_event, void *ptr_command_queue, void *pt
 error *_enqueue_read_image(void **ptr_event, void *ptr_command_queue, void *ptr_mem, size_t *origin, size_t *region, void *buffer, size_t size, size_t row_pitch, size_t slice_pitch, void **wait_for, uint32_t num_wait_for, int is_blocking);
 void populate_constants(void(*add)(const char*, const char*, long value));
 
+error *_command_queue_finish(void *ptr_command_queue);
+error *_command_queue_flush(void *ptr_command_queue);
+
 intptr_t _int_ptr(void*, class_t);
 void* _from_int_ptr(void **ptr_out, intptr_t int_ptr_value, class_t);
 error *_get_info(void *ptr, class_t class_, cl_uint param, generic_info *out);
diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index a58cbf1441da52a90a8ef0cecfc9c9079a9dcc05..3aeb863c9257447476e56225ef020478164b687c 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -425,7 +425,10 @@ class CommandQueue(_Common):
             _ffi.NULL if device is None else device.ptr, properties))
 
         self.ptr = ptr_command_queue[0]
-
+    def finish(self):
+        _handle_error(_lib._command_queue_finish(self.ptr))
+    def flush(self):
+        _handle_error(_lib._command_queue_flush(self.ptr))
 
 class MemoryObjectHolder(_Common):
     pass
diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp
index 1d60f586530aa883a8d5180292b5c2821efdc0ba..33619a43b7b035e5bc569da8ef05d8afd705946b 100644
--- a/src/c_wrapper/wrap_cl.cpp
+++ b/src/c_wrapper/wrap_cl.cpp
@@ -1074,8 +1074,7 @@ namespace pyopencl
 
     void finish()
     {
-      // TODO
-      // PYOPENCL_CALL_GUARDED_THREADED(clFinish, (m_queue));
+      PYOPENCL_CALL_GUARDED_THREADED(clFinish, (m_queue));
     }
   };
 
@@ -3412,6 +3411,21 @@ error *_create_image_3d(
 
 // }}}
 
+::error *_command_queue_finish(void *ptr_command_queue)
+{
+  BEGIN_C_HANDLE_ERROR
+  static_cast<pyopencl::command_queue*>(ptr_command_queue)->finish();
+  END_C_HANDLE_ERROR
+  return 0;
+}
+
+::error *_command_queue_flush(void *ptr_command_queue)
+{
+  BEGIN_C_HANDLE_ERROR
+  static_cast<pyopencl::command_queue*>(ptr_command_queue)->flush();
+  END_C_HANDLE_ERROR
+  return 0;
+}
 
 intptr_t _int_ptr(void* ptr, class_t class_) {
 #define INT_PTR(CLSU, CLS) return (intptr_t)(static_cast<pyopencl::CLS*>(ptr)->data());