diff --git a/doc/source/misc.rst b/doc/source/misc.rst
index 3bdc94318829b5221b7a14d714c9627f0b4ecafa..ab349c4c8bddae5f9b430340f7d6857883fb0b58 100644
--- a/doc/source/misc.rst
+++ b/doc/source/misc.rst
@@ -84,8 +84,9 @@ Version 2011.1
   :func:`pyopencl.enqueue_write_image`,
   :func:`pyopencl.enqueue_map_buffer`,
   :func:`pyopencl.enqueue_map_image`.
-* Add :mod:`pycuda.reduction`.
+* Add :mod:`pyopencl.reduction`.
 * Add :ref:`reductions`.
+* Add :meth:`MemoryObject.get_host_array`.
 
 Version 0.92
 ------------
diff --git a/doc/source/runtime.rst b/doc/source/runtime.rst
index 0359c6ddce3a8319a431449f379bc1284f47108c..dd7fd91a9a853e641f996e36cf995e5869c05acb 100644
--- a/doc/source/runtime.rst
+++ b/doc/source/runtime.rst
@@ -256,16 +256,19 @@ Memory
         may be used as attributes on instances of this class
         to directly query info attributes.
 
+    .. attribute:: hostbuf
+
     .. method:: get_info(param)
 
         See :class:`mem_info` for values of *param*.
 
-    .. attribute:: hostbuf
+    .. method:: release()
 
-        Contains the *hostbuf* parameter if the MemoryObject was constructed
-        with :attr:`mem_flags.USE_HOST_PTR`.
+    .. method:: get_host_array(shape, dtype, order="C")
 
-    .. method:: release()
+        Return the memory object's associated host memory 
+        area as a :class:`numpy.ndarray` of the given *shape*,
+        *dtype* and *order*.
 
     |comparable|
 
diff --git a/src/wrapper/wrap_cl.hpp b/src/wrapper/wrap_cl.hpp
index 510ad6694fb9782279732d1285149f097745d654..719655f9a9c7b89c382dc1201a3fd8ffb7427153 100644
--- a/src/wrapper/wrap_cl.hpp
+++ b/src/wrapper/wrap_cl.hpp
@@ -2957,7 +2957,8 @@ namespace pyopencl
         PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name,
             size_t);
       case CL_MEM_HOST_PTR:
-        return m_hostbuf;
+        throw pyopencl::error("MemoryObject.get_info", CL_INVALID_VALUE,
+            "Use MemoryObject.get_host_array to get host pointer.");
       case CL_MEM_MAP_COUNT:
         PYOPENCL_GET_INTEGRAL_INFO(MemObject, m_mem, param_name,
             cl_uint);
@@ -3008,6 +3009,65 @@ namespace pyopencl
     }
   }
 
+  inline
+  py::handle<> get_mem_obj_host_array(
+      py::object mem_obj_py,
+      py::object shape, py::object dtype, 
+      py::object order_py)
+  {
+    memory_object const &mem_obj = 
+      py::extract<memory_object const &>(mem_obj_py);
+    PyArray_Descr *tp_descr;
+    if (PyArray_DescrConverter(dtype.ptr(), &tp_descr) != NPY_SUCCEED)
+      throw py::error_already_set();
+
+    py::extract<npy_intp> shape_as_int(shape);
+    std::vector<npy_intp> dims;
+
+    if (shape_as_int.check())
+      dims.push_back(shape_as_int());
+    else
+      std::copy(
+          py::stl_input_iterator<npy_intp>(shape),
+          py::stl_input_iterator<npy_intp>(),
+          back_inserter(dims));
+
+    NPY_ORDER order = PyArray_CORDER;
+    PyArray_OrderConverter(order_py.ptr(), &order);
+
+    int ary_flags = 0;
+    if (order == PyArray_FORTRANORDER)
+      ary_flags |= NPY_FARRAY;
+    else if (order == PyArray_CORDER)
+      ary_flags |= NPY_CARRAY;
+    else
+      throw std::runtime_error("unrecognized order specifier");
+
+    void *host_ptr;
+    size_t mem_obj_size;
+    PYOPENCL_CALL_GUARDED(clGetMemObjectInfo,
+        (mem_obj.data(), CL_MEM_HOST_PTR, sizeof(host_ptr),
+         &host_ptr, 0));
+    PYOPENCL_CALL_GUARDED(clGetMemObjectInfo,
+        (mem_obj.data(), CL_MEM_SIZE, sizeof(mem_obj_size),
+         &mem_obj_size, 0));
+
+    py::handle<> result = py::handle<>(PyArray_NewFromDescr(
+        &PyArray_Type, tp_descr,
+        dims.size(), &dims.front(), /*strides*/ NULL,
+        host_ptr, ary_flags, /*obj*/NULL));
+
+    if (PyArray_NBYTES(result.get()) > mem_obj_size)
+      throw pyopencl::error("MemoryObject.get_host_array", 
+          CL_INVALID_VALUE,
+          "Resulting array is larger than memory object.");
+
+    PyArray_BASE(result.get()) = mem_obj_py.ptr();
+    Py_INCREF(mem_obj_py.ptr());
+
+    return result;
+  }
+
   // }}}
 
 }
diff --git a/src/wrapper/wrap_cl_part_1.cpp b/src/wrapper/wrap_cl_part_1.cpp
index 495d7af8b283c6b62d0bea83ba46ca2ce637b7f5..233f7db05f6131f1e2dac132adce66cf310ce15b 100644
--- a/src/wrapper/wrap_cl_part_1.cpp
+++ b/src/wrapper/wrap_cl_part_1.cpp
@@ -121,6 +121,8 @@ void pyopencl_expose_part_1()
     py::class_<cls, boost::noncopyable>("MemoryObject", py::no_init)
       .DEF_SIMPLE_METHOD(get_info)
       .DEF_SIMPLE_METHOD(release)
+      .def("get_host_array", get_mem_obj_host_array,
+          (py::arg("shape"), py::arg("dtype"), py::arg("order")="C"))
       .add_property("obj_ptr", &cls::obj_ptr)
       .add_property("hostbuf", &cls::hostbuf)
       .def(py::self == py::self)