diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 0.4.3.7
+
+* Changes needed for template-haskell-2.17.
+
 # 0.4.3.6
 
 * Bumped th-abstraction.
diff --git a/microlens-th.cabal b/microlens-th.cabal
--- a/microlens-th.cabal
+++ b/microlens-th.cabal
@@ -1,5 +1,5 @@
 name:                microlens-th
-version:             0.4.3.6
+version:             0.4.3.7
 synopsis:            Automatic generation of record lenses for microlens
 description:
   This package lets you automatically generate lenses for data types; code was extracted from the lens package, and therefore generated lenses are fully compatible with ones generated by lens (and can be used both from lens and microlens).
@@ -41,7 +41,7 @@
                      , containers >=0.4.0 && <0.7
                      , transformers
                      -- lens has >=2.4, but GHC 7.4 shipped with 2.7
-                     , template-haskell >=2.7 && <2.17
+                     , template-haskell >=2.7 && <2.18
                      , th-abstraction >=0.2.1 && <0.5
 
   ghc-options:
diff --git a/src/Lens/Micro/TH.hs b/src/Lens/Micro/TH.hs
--- a/src/Lens/Micro/TH.hs
+++ b/src/Lens/Micro/TH.hs
@@ -79,6 +79,7 @@
 import           Lens.Micro.TH.Internal
 import           Language.Haskell.TH
 import qualified Language.Haskell.TH.Datatype as D
+import qualified Language.Haskell.TH.Datatype.TyVarBndr as D
 
 #if __GLASGOW_HASKELL__ < 710
 import           Control.Applicative
@@ -809,7 +810,7 @@
            | otherwise = [FunDep [c] vars]
 
 
-  classD (cxt[]) className (map PlainTV (c:vars)) fd
+  classD (cxt[]) className (map D.plainTV (c:vars)) fd
     $ sigD methodName (return (''Lens' `conAppsT` [VarT c, s']))
     : concat
       [ [sigD defName (return ty)
@@ -1007,7 +1008,7 @@
 
 makeFieldClass :: OpticStab -> Name -> Name -> DecQ
 makeFieldClass defType className methodName =
-  classD (cxt []) className [PlainTV s, PlainTV a] [FunDep [s] [a]]
+  classD (cxt []) className [D.plainTV s, D.plainTV a] [FunDep [s] [a]]
          [sigD methodName (return methodType)]
   where
   methodType = quantifyType' (Set.fromList [s,a])
@@ -1180,18 +1181,13 @@
 
 -- Perform a limited substitution on type variables. This is used
 -- when unifying rank-2 fields when trying to achieve a Getter or Fold.
-limitedSubst :: Map Name Type -> TyVarBndr -> Q TyVarBndr
-limitedSubst sub (PlainTV n)
-  | Just r <- Map.lookup n sub =
-       case r of
-         VarT m -> limitedSubst sub (PlainTV m)
-         _ -> fail "Unable to unify exotic higher-rank type"
-limitedSubst sub (KindedTV n k)
-  | Just r <- Map.lookup n sub =
+limitedSubst :: Map Name Type -> D.TyVarBndrSpec -> Q D.TyVarBndrSpec
+limitedSubst sub tv
+  | Just r <- Map.lookup (D.tvName tv) sub =
        case r of
-         VarT m -> limitedSubst sub (KindedTV m k)
+         VarT m -> limitedSubst sub (D.mapTVName (const m) tv)
          _ -> fail "Unable to unify exotic higher-rank type"
-limitedSubst _ tv = return tv
+  | otherwise = return tv
 
 -- Apply a substitution to a type. This is used after unifying
 -- the types of the fields in unifyTypes.
diff --git a/src/Lens/Micro/TH/Internal.hs b/src/Lens/Micro/TH/Internal.hs
--- a/src/Lens/Micro/TH/Internal.hs
+++ b/src/Lens/Micro/TH/Internal.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TypeSynonymInstances #-}
 
 #ifndef MIN_VERSION_template_haskell
 #define MIN_VERSION_template_haskell(x,y,z) (defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 706)
@@ -53,6 +54,7 @@
 import           Data.Maybe
 import           Lens.Micro
 import           Language.Haskell.TH
+import           Language.Haskell.TH.Datatype.TyVarBndr
 
 #if __GLASGOW_HASKELL__ < 710
 import           Control.Applicative
@@ -64,9 +66,8 @@
   -- | Extract (or modify) the 'Name' of something
   name :: Lens' t Name
 
-instance HasName TyVarBndr where
-  name f (PlainTV n) = PlainTV <$> f n
-  name f (KindedTV n k) = (`KindedTV` k) <$> f n
+instance HasName (TyVarBndr_ flag) where
+  name = traverseTVName
 
 instance HasName Name where
   name = id
@@ -96,7 +97,7 @@
   -- the 'Traversal' laws, when in doubt generate your names with 'newName'.
   typeVarsEx :: Set Name -> Traversal' t Name
 
-instance HasTypeVars TyVarBndr where
+instance HasTypeVars (TyVarBndr_ flag) where
   typeVarsEx s f b
     | Set.member (b^.name) s = pure b
     | otherwise              = name f b
@@ -156,6 +157,9 @@
   typeVarsEx s f (ForallVisT bs ty)   = ForallVisT bs <$> typeVarsEx s' f ty
        where s' = s `Set.union` setOf typeVars bs
 #endif
+#if MIN_VERSION_template_haskell(2,17,0)
+  typeVarsEx _ _ t@MulArrowT{}        = pure t
+#endif
 
 #if !MIN_VERSION_template_haskell(2,10,0)
 instance HasTypeVars Pred where
@@ -215,7 +219,7 @@
 quantifyType' :: Set Name -> Cxt -> Type -> Type
 quantifyType' exclude c t = ForallT vs c t
   where
-    vs = map PlainTV
+    vs = map plainTVSpecified
        $ filter (`Set.notMember` exclude)
        $ nub -- stable order
        $ toListOf typeVars t
@@ -233,6 +237,6 @@
 setOf :: Ord a => Getting (Endo [a]) s a -> s -> Set a
 setOf l s = Set.fromList (s ^.. l)
 
-_ForallT :: Traversal' Type ([TyVarBndr], Cxt, Type)
+_ForallT :: Traversal' Type ([TyVarBndrSpec], Cxt, Type)
 _ForallT f (ForallT a b c) = (\(x, y, z) -> ForallT x y z) <$> f (a, b, c)
 _ForallT _ other = pure other
