diff --git a/lib/rouge/demos/epp b/lib/rouge/demos/epp
new file mode 100644
index 0000000000..e8dececdd8
--- /dev/null
+++ b/lib/rouge/demos/epp
@@ -0,0 +1,4 @@
+<%- |
+ Optional[String] $title,
+| -%>
+
<%= $title %>
diff --git a/lib/rouge/lexers/epp.rb b/lib/rouge/lexers/epp.rb
new file mode 100644
index 0000000000..a6fb0acbf7
--- /dev/null
+++ b/lib/rouge/lexers/epp.rb
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*- #
+
+module Rouge
+ module Lexers
+ class EPP < TemplateLexer
+ title "EPP"
+ desc "Embedded Puppet template files"
+
+ tag 'epp'
+
+ filenames '*.epp'
+
+ def initialize(opts={})
+ @puppet_lexer = Puppet.new(opts)
+
+ super(opts)
+ end
+
+ start do
+ parent.reset!
+ @puppet_lexer.reset!
+ end
+
+ open = /<%%|<%=|<%#|(<%-|<%)(\s*?\|)?/
+ close = /%%>|(\|\s*?)?(-%>|%>)/
+
+ state :root do
+ rule /<%#/, Comment, :comment
+
+ rule open, Comment::Preproc, :puppet
+
+ rule /.+?(?=#{open})|.+/m do
+ delegate parent
+ end
+ end
+
+ state :comment do
+ rule close, Comment, :pop!
+ rule /.+?(?=#{close})|.+/m, Comment
+ end
+
+ state :puppet do
+ rule close, Comment::Preproc, :pop!
+
+ rule /.+?(?=#{close})|.+/m do
+ delegate @puppet_lexer
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lexers/epp_spec.rb b/spec/lexers/epp_spec.rb
new file mode 100644
index 0000000000..da9db1a733
--- /dev/null
+++ b/spec/lexers/epp_spec.rb
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*- #
+
+describe Rouge::Lexers::EPP do
+ let(:subject) { Rouge::Lexers::EPP.new }
+
+ describe 'guessing' do
+ include Support::Guessing
+
+ it 'guesses by filename' do
+ assert_guess :filename => 'foo.html.epp'
+ end
+ end
+end
diff --git a/spec/visual/samples/epp b/spec/visual/samples/epp
new file mode 100644
index 0000000000..a33b3fa699
--- /dev/null
+++ b/spec/visual/samples/epp
@@ -0,0 +1,24 @@
+<%- | Boolean $keys_enable,
+ String $keys_file,
+ Array $keys_trusted,
+ String $keys_requestkey,
+ String $keys_controlkey
+| -%>
+<%# Parameter tag ↑ -%>
+
+<%# Non-printing tag ↓ -%>
+<% if $keys_enable { -%>
+
+<%# Expression-printing tag ↓ -%>
+keys <%= $keys_file %>
+<% unless $keys_trusted =~ Array[Data,0,0] { -%>
+trustedkey <%= $keys_trusted.join(' ') %>
+<% } -%>
+<% if $keys_requestkey =~ String[1] { -%>
+requestkey <%= $keys_requestkey %>
+<% } -%>
+<% if $keys_controlkey =~ String[1] { -%>
+controlkey <%= $keys_controlkey %>
+<% } -%>
+
+<% } -%>