diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Changelog
+
+## [0.0.0.0] - 2022-03-21
+
+Initial release: `GenValidity (CI a)`
diff --git a/bench/Main.hs b/bench/Main.hs
new file mode 100644
--- /dev/null
+++ b/bench/Main.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE TypeApplications #-}
+
+module Main where
+
+import Criterion.Main
+import Data.CaseInsensitive (CI)
+import Data.GenValidity.CaseInsensitive ()
+import Data.GenValidity.Criterion
+
+main :: IO ()
+main =
+  defaultMain
+    [ genValidBench @(CI String)
+    ]
diff --git a/genvalidity-case-insensitive.cabal b/genvalidity-case-insensitive.cabal
new file mode 100644
--- /dev/null
+++ b/genvalidity-case-insensitive.cabal
@@ -0,0 +1,69 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.34.7.
+--
+-- see: https://github.com/sol/hpack
+
+name:           genvalidity-case-insensitive
+version:        0.0.0.0
+synopsis:       GenValidity support for case-insensitive
+category:       Testing
+homepage:       https://github.com/NorfairKing/validity#readme
+bug-reports:    https://github.com/NorfairKing/validity/issues
+license:        MIT
+build-type:     Simple
+extra-source-files:
+    CHANGELOG.md
+
+source-repository head
+  type: git
+  location: https://github.com/NorfairKing/validity
+
+library
+  exposed-modules:
+      Data.GenValidity.CaseInsensitive
+  other-modules:
+      Paths_genvalidity_case_insensitive
+  hs-source-dirs:
+      src
+  build-depends:
+      base >=4.7 && <5
+    , case-insensitive
+    , genvalidity >=1.0
+    , validity-case-insensitive
+  default-language: Haskell2010
+
+test-suite genvalidity-case-insensitive-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Data.GenValidity.CaseInsensitiveSpec
+      Paths_genvalidity_case_insensitive
+  hs-source-dirs:
+      test
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
+  build-depends:
+      base >=4.7 && <5
+    , case-insensitive
+    , genvalidity-case-insensitive
+    , genvalidity-hspec
+    , hspec
+  default-language: Haskell2010
+
+benchmark genvalidity-case-insensitive-bench
+  type: exitcode-stdio-1.0
+  main-is: Main.hs
+  other-modules:
+      Paths_genvalidity_case_insensitive
+  hs-source-dirs:
+      bench
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
+  build-depends:
+      QuickCheck
+    , base >=4.7 && <5
+    , case-insensitive
+    , criterion
+    , genvalidity
+    , genvalidity-case-insensitive
+    , genvalidity-criterion
+  default-language: Haskell2010
diff --git a/src/Data/GenValidity/CaseInsensitive.hs b/src/Data/GenValidity/CaseInsensitive.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/GenValidity/CaseInsensitive.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Data.GenValidity.CaseInsensitive where
+
+import Data.CaseInsensitive (CI)
+import qualified Data.CaseInsensitive as CI
+import Data.GenValidity
+import Data.Validity.CaseInsensitive ()
+
+instance (Eq a, CI.FoldCase a, GenValid a) => GenValid (CI a) where
+  genValid = CI.mk <$> genValid
+
+  -- We have to filter out c again, because for values like String, case
+  -- folding means we could end up with the same string again (according to
+  -- Eq).
+  shrinkValid c = filter (/= c) . fmap CI.mk . shrinkValid . CI.original $ c
diff --git a/test/Data/GenValidity/CaseInsensitiveSpec.hs b/test/Data/GenValidity/CaseInsensitiveSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Data/GenValidity/CaseInsensitiveSpec.hs
@@ -0,0 +1,16 @@
+{-# LANGUAGE TypeApplications #-}
+
+module Data.GenValidity.CaseInsensitiveSpec
+  ( spec,
+  )
+where
+
+import Data.CaseInsensitive (CI)
+import Data.GenValidity.CaseInsensitive ()
+import Test.Hspec
+import Test.Validity
+
+spec :: Spec
+spec = do
+  genValidSpec @(CI String)
+  shrinkValidSpec @(CI String)
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
