diff --git a/llvm-general.cabal b/llvm-general.cabal
--- a/llvm-general.cabal
+++ b/llvm-general.cabal
@@ -1,5 +1,5 @@
 name: llvm-general
-version: 3.3.4.0
+version: 3.3.4.1
 license: BSD3
 license-file: LICENSE
 author: Benjamin S.Scarlet <fgthb0@greynode.net>
@@ -34,7 +34,7 @@
   type: git
   location: git://github.com/bscarlet/llvm-general.git
   branch: llvm-3.3
-  tag: v3.3.4.0
+  tag: v3.3.4.1
 
 flag shared-llvm
   description: link against llvm shared rather than static library
diff --git a/src/LLVM/General/Internal/FFI/Type.hs b/src/LLVM/General/Internal/FFI/Type.hs
--- a/src/LLVM/General/Internal/FFI/Type.hs
+++ b/src/LLVM/General/Internal/FFI/Type.hs
@@ -140,3 +140,7 @@
 -- | <http://llvm.org/doxygen/group__LLVMCCoreTypeFloat.html#gac2491184fc3d8631c7b264c067f2f761>
 foreign import ccall unsafe "LLVMPPCFP128TypeInContext" ppcFP128TypeInContext ::
   Ptr Context -> IO (Ptr Type)
+
+-- | <http://llvm.org/doxygen/classllvm_1_1Type.html#a28fdf240b8220065bc60d6d1b1a2f174>
+foreign import ccall unsafe "LLVM_General_MetadataTypeInContext" metadataTypeInContext ::
+  Ptr Context -> IO (Ptr Type)
diff --git a/src/LLVM/General/Internal/FFI/TypeC.cpp b/src/LLVM/General/Internal/FFI/TypeC.cpp
--- a/src/LLVM/General/Internal/FFI/TypeC.cpp
+++ b/src/LLVM/General/Internal/FFI/TypeC.cpp
@@ -32,5 +32,8 @@
 	return unwrap<ArrayType>(ArrayTy)->getNumElements();
 }
 
+LLVMTypeRef LLVM_General_MetadataTypeInContext(LLVMContextRef C) {
+  return wrap(Type::getMetadataTy(*unwrap(C)));
+}
 
 }
diff --git a/src/LLVM/General/Internal/Instruction.hs b/src/LLVM/General/Internal/Instruction.hs
--- a/src/LLVM/General/Internal/Instruction.hs
+++ b/src/LLVM/General/Internal/Instruction.hs
@@ -59,6 +59,12 @@
           else return zip `ap` decodeM (n', ks) `ap` decodeM (n', ps)
   getMetadata 4
 
+setMD :: Ptr FFI.Instruction -> A.InstructionMetadata -> EncodeAST ()
+setMD i md = forM_ md $ \(kindName, anode) -> do
+               kindID <- encodeM kindName
+               node <- encodeM anode
+               liftIO $ FFI.setMetadata i kindID node
+
 instance DecodeM DecodeAST A.Terminator (Ptr FFI.Instruction) where
   decodeM i = scopeAnyCont $ do
     n <- liftIO $ FFI.getInstructionDefOpcode i
@@ -214,10 +220,7 @@
       } -> do
         i <- liftIO $ FFI.buildUnreachable builder
         return $ FFI.upCast i
-    forM (A.metadata' t) $ \(k, mdn) -> do
-      k <- encodeM k
-      mdn <- encodeM mdn
-      liftIO $ FFI.setMetadata t' k mdn
+    setMD t' (A.metadata' t)
     return t'      
 
 $(do
@@ -336,14 +339,13 @@
         builder <- gets encodeStateBuilder
         let return' i = return (FFI.upCast i, return ())
         s <- encodeM ""
-        $(
+        (inst, act) <- $(
           [|
             case o of
               A.ICmp { 
-                A.iPredicate = pred, 
-                A.operand0 = op0, 
-                A.operand1 = op1, 
-                A.metadata = [] 
+                A.iPredicate = pred,
+                A.operand0 = op0,
+                A.operand1 = op1
               } -> do
                 op0' <- encodeM op0
                 op1' <- encodeM op1
@@ -351,10 +353,9 @@
                 i <- liftIO $ FFI.buildICmp builder pred op0' op1' s
                 return' i
               A.FCmp {
-                A.fpPredicate = pred, 
-                A.operand0 = op0, 
-                A.operand1 = op1, 
-                A.metadata = [] 
+                A.fpPredicate = pred,
+                A.operand0 = op0,
+                A.operand1 = op1
               } -> do
                 op0' <- encodeM op0
                 op1' <- encodeM op1
@@ -378,8 +379,7 @@
                 A.returnAttributes = rAttrs,
                 A.function = f,
                 A.arguments = args,
-                A.functionAttributes = fAttrs,
-                A.metadata = []
+                A.functionAttributes = fAttrs
               } -> do
                 fv <- encodeM f
                 let (argvs, argAttrs) = unzip args
@@ -470,8 +470,7 @@
                 A.volatile = vol,
                 A.address = a,
                 A.alignment = al,
-                A.maybeAtomicity = mat,
-                A.metadata = []
+                A.maybeAtomicity = mat
               } -> do
                  a' <- encodeM a
                  al <- encodeM al
@@ -484,8 +483,7 @@
                 A.address = a, 
                 A.value = v, 
                 A.maybeAtomicity = mat, 
-                A.alignment = al, 
-                A.metadata = []
+                A.alignment = al
               } -> do
                  a' <- encodeM a
                  v' <- encodeM v
@@ -507,8 +505,7 @@
               A.CmpXchg { 
                 A.volatile = vol, 
                 A.address = a, A.expected = e, A.replacement = r,
-                A.atomicity = at,
-                A.metadata = []
+                A.atomicity = at
               } -> do
                  a' <- encodeM a
                  e' <- encodeM e
@@ -522,8 +519,7 @@
                 A.rmwOperation = rmwOp,
                 A.address = a,
                 A.value = v,
-                A.atomicity = at,
-                A.metadata = []
+                A.atomicity = at
               } -> do
                  a' <- encodeM a
                  v' <- encodeM v
@@ -542,8 +538,7 @@
                          "nsw" -> [Left [| encodeM $(TH.dyn s) |] ]
                          "nuw" -> [Left [| encodeM $(TH.dyn s) |] ]
                          "exact" -> [Left [| encodeM $(TH.dyn s) |] ]
-                         "metadata" -> 
-                           [Right [| unless (List.null $(TH.dyn s)) $ error "can't handle metadata yet" |]]
+                         "metadata" -> [Right [| return () |] ]
                          _ -> error $ "unhandled instruction field " ++ show s
                      in
                      TH.caseE [| o |] [
@@ -591,6 +586,8 @@
 
            |]
          )
+        setMD inst (A.metadata o)
+        return (inst, act)
    |]
  )
 
diff --git a/src/LLVM/General/Internal/Type.hs b/src/LLVM/General/Internal/Type.hs
--- a/src/LLVM/General/Internal/Type.hs
+++ b/src/LLVM/General/Internal/Type.hs
@@ -98,6 +98,7 @@
         packed <- encodeM packed
         liftIO $ FFI.structTypeInContext context ets packed
       A.NamedTypeReference n -> lookupNamedType n
+      A.MetadataType -> liftIO $ FFI.metadataTypeInContext context
 
 instance DecodeM DecodeAST A.Type (Ptr FFI.Type) where
   decodeM t = scopeAnyCont $ do
