diff --git a/HSCParser.hs b/HSCParser.hs
index d855cf10e57d1cd691b563491ebc2fd38b7b046f..478faf0679665dde5c2bfac1618a2e169b185181 100644
--- a/HSCParser.hs
+++ b/HSCParser.hs
@@ -100,6 +100,9 @@ anyChar_ = do
 any2Chars_ :: Parser ()
 any2Chars_ = anyChar_ >> anyChar_
 
+any3Chars_ :: Parser ()
+any3Chars_ = anyChar_ >> anyChar_ >> anyChar_
+
 many :: Parser a -> Parser [a]
 many p = many1 p `mplus` return []
 
@@ -161,12 +164,57 @@ text = do
                 _ -> do
                     return () `fakeOutput` unescapeHashes symb
                     text
-        '\"':_    -> do anyChar_; hsString '\"'; text
-        '\'':_    -> do anyChar_; hsString '\''; text
-        '{':'-':_ -> do any2Chars_; linePragma `mplus`
-                                    columnPragma `mplus`
-                                    hsComment; text
-        _:_       -> do anyChar_; text
+        '\"':_        -> do anyChar_; hsString '\"'; text
+        -- See Note [Single Quotes]
+        '\'':'\\':_ -> do any2Chars_; hsString '\''; text -- Case 1
+        '\'':d:'\'':_ -> do any3Chars_; text -- Case 2
+        '\'':d:_ | isSpace d -> do -- Case 3
+          any2Chars_
+          manySatisfy_ (\c' -> isSpace c')
+          manySatisfy_ (\c' -> isAlphaNum c' || c' == '_' || c' == '\'')
+          text
+        '\'':_ -> do -- Case 4
+          anyChar_
+          manySatisfy_ (\c' -> isAlphaNum c' || c' == '_' || c' == '\'')
+          text
+        '{':'-':_ -> do
+          any2Chars_
+          linePragma `mplus` columnPragma `mplus` hsComment
+          text
+        _:_           -> do anyChar_; text
+
+-- Note [Single Quotes]
+--
+-- hsc2hs performs some tricks to figure out if we are looking at character
+-- literal or a promoted data constructor. In order, the cases considered are:
+--
+-- 1. quote-backslash: An escape sequence character literal. Since these
+--    escape sequences have several different possible lengths, hsc2hs will
+--    consume everything after this until another single quote is encountered.
+-- 2. quote-any-quote: A character literal. Consumes the triplet.
+-- 3. quote-space: Here, the order of the patterns becomes important. This
+--    case and the case below handle promoted data constructors. This one
+--    is to handle data constructor that end in a quote. They have special
+--    syntax for promotion that requires adding a leading space. After an
+--    arbitrary number of initial space characters, consume
+--    all alphanumeric characters and quotes, considering them part of the
+--    identifier.
+-- 4. quote: If nothing else matched, we assume we are dealing with a normal
+--    promoted data constructor. Consume all alphanumeric characters and
+--    quotes, considering them part of the identifier.
+--
+-- Here are some lines of code for which at one of the described cases
+-- would be matched at some point:
+--
+--     data Foo = Foo' | Bar
+--
+--     main :: IO ()
+--     main = do
+-- 1>    putChar 'x'
+-- 2>    putChar '\NUL'
+-- 3>    let y = Proxy :: Proxy ' Foo'
+-- 4>    let x = Proxy :: Proxy 'Bar
+--       pure ()
 
 hsString :: Char -> Parser ()
 hsString quote = do
diff --git a/changelog.md b/changelog.md
index 07812af836b060f7352cd731440ce118784c8102..33e88774c741ce58e748ce2fd72fbef8dc229b99 100644
--- a/changelog.md
+++ b/changelog.md
@@ -6,6 +6,9 @@
  - Support for non-x86 platforms should be significantly more robust due to
    improvements in `hsc2hs`'s assembly parser
 
+ - Add support for haskell files that use a leading single quote for promoted
+   data constructors.
+
 ## 0.68.4
 
  - Add support to read command line arguments supplied via response files