diff --git a/Control/Monad/Primitive.hs b/Control/Monad/Primitive.hs
--- a/Control/Monad/Primitive.hs
+++ b/Control/Monad/Primitive.hs
@@ -15,10 +15,11 @@
   PrimMonad(..), RealWorld, primitive_,
   primToPrim, primToIO, primToST,
   unsafePrimToPrim, unsafePrimToIO, unsafePrimToST,
-  unsafeInlinePrim, unsafeInlineIO, unsafeInlineST
+  unsafeInlinePrim, unsafeInlineIO, unsafeInlineST,
+  touch
 ) where
 
-import GHC.Prim   ( State#, RealWorld )
+import GHC.Prim   ( State#, RealWorld, touch# )
 import GHC.Base   ( unsafeCoerce#, realWorld# )
 import GHC.IOBase ( IO(..) )
 import GHC.ST     ( ST(..) )
@@ -89,4 +90,8 @@
 unsafeInlineST :: ST s a -> a
 {-# INLINE unsafeInlineST #-}
 unsafeInlineST = unsafeInlinePrim
+
+touch :: PrimMonad m => a -> m ()
+touch x = unsafePrimToPrim
+        $ (primitive (\s -> case touch# x s of { s' -> (# s', () #) }) :: IO ())
 
diff --git a/Data/Primitive/Addr.hs b/Data/Primitive/Addr.hs
--- a/Data/Primitive/Addr.hs
+++ b/Data/Primitive/Addr.hs
@@ -15,7 +15,8 @@
   Addr(..),
 
   nullAddr, plusAddr, minusAddr, remAddr,
-  indexOffAddr, readOffAddr, writeOffAddr
+  indexOffAddr, readOffAddr, writeOffAddr,
+  memcpyAddr
 ) where
 
 import Control.Monad.Primitive
@@ -24,6 +25,10 @@
 import GHC.Base ( Int(..) )
 import GHC.Prim
 
+import GHC.Ptr
+import Foreign.Marshal.Utils
+
+
 -- | The null address
 nullAddr :: Addr
 nullAddr = Addr nullAddr#
@@ -61,4 +66,8 @@
 writeOffAddr :: (Prim a, PrimMonad m) => Addr -> Int -> a -> m ()
 {-# INLINE writeOffAddr #-}
 writeOffAddr (Addr addr#) (I# i#) x = primitive_ (writeOffAddr# addr# i# x)
+
+memcpyAddr :: PrimMonad m => Addr -> Addr -> Int -> m ()
+memcpyAddr (Addr dst#) (Addr src#) n
+  = unsafePrimToPrim $ copyBytes (Ptr dst#) (Ptr src#) n
 
diff --git a/Data/Primitive/ByteArray.hs b/Data/Primitive/ByteArray.hs
--- a/Data/Primitive/ByteArray.hs
+++ b/Data/Primitive/ByteArray.hs
@@ -17,9 +17,9 @@
 
   newByteArray, newPinnedByteArray, newAlignedPinnedByteArray,
   readByteArray, writeByteArray, indexByteArray,
-  unsafeFreezeByteArray,
+  unsafeFreezeByteArray, unsafeThawByteArray,
   sizeofByteArray, sizeofMutableByteArray, sameMutableByteArray,
-  byteArrayContents,
+  byteArrayContents, mutableByteArrayContents,
 
   memcpyByteArray, memcpyByteArray', memmoveByteArray, memsetByteArray
 ) where
@@ -73,6 +73,14 @@
 {-# INLINE byteArrayContents #-}
 byteArrayContents (ByteArray arr#) = Addr (byteArrayContents# arr#)
 
+-- | Yield a pointer to the array's data. This operation is only safe on
+-- /pinned/ byte arrays allocated by 'newPinnedByteArray' or
+-- 'newAlignedPinnedByteArray'.
+mutableByteArrayContents :: MutableByteArray s -> Addr
+{-# INLINE mutableByteArrayContents #-}
+mutableByteArrayContents (MutableByteArray arr#)
+  = Addr (byteArrayContents# (unsafeCoerce# arr#))
+
 -- | Check if the two arrays refer to the same memory block.
 sameMutableByteArray :: MutableByteArray s -> MutableByteArray s -> Bool
 {-# INLINE sameMutableByteArray #-}
@@ -87,6 +95,14 @@
 unsafeFreezeByteArray (MutableByteArray arr#)
   = primitive (\s# -> case unsafeFreezeByteArray# arr# s# of
                         (# s'#, arr'# #) -> (# s'#, ByteArray arr'# #))
+
+-- | Convert an immutable byte array to a mutable one without copying. The
+-- original array should not be used after the conversion.
+unsafeThawByteArray
+  :: PrimMonad m => ByteArray -> m (MutableByteArray (PrimState m))
+{-# INLINE unsafeThawByteArray #-}
+unsafeThawByteArray (ByteArray arr#)
+  = primitive (\s# -> (# s#, MutableByteArray (unsafeCoerce# arr#) #))
 
 -- | Size of the byte array.
 sizeofByteArray :: ByteArray -> Int
diff --git a/primitive.cabal b/primitive.cabal
--- a/primitive.cabal
+++ b/primitive.cabal
@@ -1,5 +1,5 @@
 Name:           primitive
-Version:        0.3
+Version:        0.3.1
 License:        BSD3
 License-File:   LICENSE
 Author:         Roman Leshchinskiy <rl@cse.unsw.edu.au>
