diff --git a/Makefile b/Makefile
index a78e9d9..3a40521 100644
--- a/Makefile
+++ b/Makefile
@@ -14,6 +14,7 @@
 #   USE_MY_SPLICE        : redefine the splice syscall if build fails without.
 #   USE_NETFILTER        : enable netfilter on Linux. Automatic.
 #   USE_PCRE             : enable use of libpcre for regex. Recommended.
+#   USE_PCRE_JIT         : enable use of libpcre jit for regex. Recommended.
 #   USE_POLL             : enable poll(). Automatic.
 #   USE_PRIVATE_CACHE    : disable shared memory cache of ssl sessions.
 #   USE_REGPARM          : enable regparm optimization. Recommended on x86.
@@ -548,6 +549,10 @@ BUILD_OPTIONS   += $(call ignore_implicit,USE_STATIC_PCRE)
 endif
 endif
 
+ifneq ($(USE_PCRE_JIT),)
+OPTIONS_CFLAGS  += -DUSE_PCRE_JIT
+endif
+
 # This one can be changed to look for ebtree files in an external directory
 EBTREE_DIR := ebtree
 
diff --git a/include/common/regex.h b/include/common/regex.h
index 60c7f42..4386740 100644
--- a/include/common/regex.h
+++ b/include/common/regex.h
@@ -27,6 +27,18 @@
 #ifdef USE_PCRE
 #include <pcre.h>
 #include <pcreposix.h>
+
+#ifdef USE_PCRE_JIT
+struct jit_regex {
+    pcre *reg;
+    pcre_extra *extra;
+};
+
+typedef struct jit_regex regexp;
+#else
+typedef regex_t regexp;
+#endif
+
 #else
 #include <regex.h>
 #endif
@@ -54,6 +66,8 @@ int exp_replace(char *dst, char *src, const char *str,	const regmatch_t *matches
 const char *check_replace_string(const char *str);
 const char *chain_regex(struct hdr_exp **head, const regex_t *preg,
 			int action, const char *replace, void *cond);
+int exec_regexp(const regexp *preg, const char *subject, int length);
+void free_regexp(regexp *preg);
 
 #endif /* _COMMON_REGEX_H */
 
diff --git a/include/types/acl.h b/include/types/acl.h
index bf5537f..37b944f 100644
--- a/include/types/acl.h
+++ b/include/types/acl.h
@@ -213,7 +213,7 @@ struct acl_pattern {
 	union {
 		void *ptr;              /* any data */
 		char *str;              /* any string  */
-		regex_t *reg;           /* a compiled regex */
+		regexp *reg;           /* a compiled regex */
 	} ptr;                          /* indirect values, allocated */
 	void(*freeptrbuf)(void *ptr);	/* a destructor able to free objects from the ptr */
 	int len;                        /* data length when required  */
diff --git a/src/acl.c b/src/acl.c
index 753f109..5dc045f 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -533,7 +533,7 @@ int acl_match_reg(struct sample *smp, struct acl_pattern *pattern)
 	old_char = smp->data.str.str[smp->data.str.len];
 	smp->data.str.str[smp->data.str.len] = 0;
 
-	if (regexec(pattern->ptr.reg, smp->data.str.str, 0, NULL, 0) == 0)
+	if (exec_regexp(pattern->ptr.reg, smp->data.str.str, smp->data.str.len) == 0)
 		ret = ACL_PAT_PASS;
 	else
 		ret = ACL_PAT_FAIL;
@@ -900,28 +900,55 @@ acl_parse_strcat(const char **text, struct acl_pattern *pattern, int *opaque, ch
 /* Free data allocated by acl_parse_reg */
 static void acl_free_reg(void *ptr)
 {
-	regfree((regex_t *)ptr);
+	free_regexp((regexp *)ptr);
 }
 
 /* Parse a regex. It is allocated. */
 int acl_parse_reg(const char **text, struct acl_pattern *pattern, int *opaque, char **err)
 {
+#ifdef USE_PCRE_JIT
+	struct jit_regex *preg;
+#else
 	regex_t *preg;
+#endif
 	int icase;
 
+#ifdef USE_PCRE_JIT
+	preg = calloc(1, sizeof(struct jit_regex));
+#else
 	preg = calloc(1, sizeof(regex_t));
+#endif
 
 	if (!preg) {
 		memprintf(err, "out of memory while loading pattern");
 		return 0;
 	}
 
+#ifdef USE_PCRE_JIT
+	icase = (pattern->flags & ACL_PAT_F_IGNORE_CASE) ? PCRE_CASELESS : 0;
+	preg->reg = pcre_compile(*text, PCRE_NO_AUTO_CAPTURE | icase, NULL, NULL,
+		NULL);
+	if (!preg->reg) {
+		free(preg);
+		memprintf(err, "regex '%s' is invalid", *text);
+		return 0;
+	}
+
+	preg->extra = pcre_study(preg->reg, PCRE_STUDY_JIT_COMPILE, NULL);
+	if (!preg->extra) {
+		pcre_free(preg->reg);
+		free(preg);
+		memprintf(err, "failed to compile regex '%s'", *text);
+		return 0;
+	}
+#else
 	icase = (pattern->flags & ACL_PAT_F_IGNORE_CASE) ? REG_ICASE : 0;
 	if (regcomp(preg, *text, REG_EXTENDED | REG_NOSUB | icase) != 0) {
 		free(preg);
 		memprintf(err, "regex '%s' is invalid", *text);
 		return 0;
 	}
+#endif
 
 	pattern->ptr.reg = preg;
 	pattern->freeptrbuf = &acl_free_reg;
diff --git a/src/regex.c b/src/regex.c
index 1455fb4..319e4ef 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -122,7 +122,23 @@ const char *chain_regex(struct hdr_exp **head, const regex_t *preg,
 	return NULL;
 }
 
+int exec_regexp(const regexp *preg, const char *subject, int length) {
+#ifdef USE_PCRE_JIT
+	return pcre_exec(preg->reg, preg->extra, subject, length, 0, 0, NULL, 0);
+#else
+	return regexec(preg, subject, 0, NULL, 0);
+#endif
+}
 
+void free_regexp(regexp *preg) {
+#ifdef USE_PCRE_JIT
+	pcre_free_study(preg->extra);
+	pcre_free(preg->reg);
+	free(preg);
+#else
+	regfree(preg);
+#endif
+}
 
 /*
  * Local variables:
