diff --git a/easyrules-core/src/main/java/org/easyrules/core/RuleDefinitionValidator.java b/easyrules-core/src/main/java/org/easyrules/core/RuleDefinitionValidator.java
index 788279c..ca9e336 100644
--- a/easyrules-core/src/main/java/org/easyrules/core/RuleDefinitionValidator.java
+++ b/easyrules-core/src/main/java/org/easyrules/core/RuleDefinitionValidator.java
@@ -93,7 +93,7 @@ class RuleDefinitionValidator {
     }
 
     private boolean isRuleClassWellDefined(final Object rule) {
-        return rule.getClass().isAnnotationPresent(Rule.class);
+        return Utils.isAnnotationPresent(Rule.class, rule.getClass());
     }
 
     private boolean isConditionMethodWellDefined(final Method method) {
diff --git a/easyrules-core/src/main/java/org/easyrules/core/RuleProxy.java b/easyrules-core/src/main/java/org/easyrules/core/RuleProxy.java
index 4901bca..dc07910 100644
--- a/easyrules-core/src/main/java/org/easyrules/core/RuleProxy.java
+++ b/easyrules-core/src/main/java/org/easyrules/core/RuleProxy.java
@@ -146,7 +146,7 @@ class RuleProxy implements InvocationHandler {
     }
 
     private Rule getRuleAnnotation() {
-        return getTargetClass().getAnnotation(Rule.class);
+        return Utils.findAnnotation(Rule.class, getTargetClass());
     }
 
     private String getRuleName() {
diff --git a/easyrules-core/src/main/java/org/easyrules/util/Utils.java b/easyrules-core/src/main/java/org/easyrules/util/Utils.java
index 12a4d49..2feeb23 100644
--- a/easyrules-core/src/main/java/org/easyrules/util/Utils.java
+++ b/easyrules-core/src/main/java/org/easyrules/util/Utils.java
@@ -1,5 +1,6 @@
 package org.easyrules.util;
 
+import java.lang.annotation.Annotation;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
@@ -74,6 +75,32 @@ public final class Utils {
         return interfaces;
     }
 
+    @SuppressWarnings("unchecked")
+    public static <A extends Annotation> A findAnnotation(
+            final Class<? extends Annotation> targetAnnotation, final Class annotatedType) {
+
+        checkNotNull(targetAnnotation, "targetAnnotation");
+        checkNotNull(annotatedType, "annotatedType");
+
+        Annotation foundAnnotation = annotatedType.getAnnotation(targetAnnotation);
+        if (foundAnnotation == null) {
+            for (Annotation annotation : annotatedType.getAnnotations()) {
+                Class<? extends Annotation> annotationType = annotation.annotationType();
+                if (annotationType.isAnnotationPresent(targetAnnotation)) {
+                    foundAnnotation = annotationType.getAnnotation(targetAnnotation);
+                    break;
+                }
+            }
+        }
+        return (A) foundAnnotation;
+    }
+
+    public static boolean isAnnotationPresent(
+            final Class<? extends Annotation> targetAnnotation, final Class annotatedType) {
+
+        return findAnnotation(targetAnnotation, annotatedType) != null;
+    }
+
     public static void checkNotNull(final Object argument, final String argumentName) {
         if (argument == null) {
             throw new IllegalArgumentException(format("The %s must not be null", argumentName));
diff --git a/easyrules-core/src/test/java/org/easyrules/annotation/AnnotatedRuleWithMetaRuleAnnotation.java b/easyrules-core/src/test/java/org/easyrules/annotation/AnnotatedRuleWithMetaRuleAnnotation.java
new file mode 100644
index 0000000..0378f46
--- /dev/null
+++ b/easyrules-core/src/test/java/org/easyrules/annotation/AnnotatedRuleWithMetaRuleAnnotation.java
@@ -0,0 +1,14 @@
+package org.easyrules.annotation;
+
+@MetaRule
+public class AnnotatedRuleWithMetaRuleAnnotation {
+
+    @Condition
+    public boolean when() {
+        return true;
+    }
+
+    @Action
+    public void then() throws Exception {
+    }
+}
diff --git a/easyrules-core/src/test/java/org/easyrules/annotation/MetaRule.java b/easyrules-core/src/test/java/org/easyrules/annotation/MetaRule.java
new file mode 100644
index 0000000..8fab0ea
--- /dev/null
+++ b/easyrules-core/src/test/java/org/easyrules/annotation/MetaRule.java
@@ -0,0 +1,12 @@
+package org.easyrules.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Rule
+public @interface MetaRule {
+}
diff --git a/easyrules-core/src/test/java/org/easyrules/core/RuleDefinitionValidatorTest.java b/easyrules-core/src/test/java/org/easyrules/core/RuleDefinitionValidatorTest.java
index 6904f81..188c831 100644
--- a/easyrules-core/src/test/java/org/easyrules/core/RuleDefinitionValidatorTest.java
+++ b/easyrules-core/src/test/java/org/easyrules/core/RuleDefinitionValidatorTest.java
@@ -22,6 +22,11 @@ public class RuleDefinitionValidatorTest {
         ruleDefinitionValidator.validateRuleDefinition(new Object());
     }
 
+    @Test
+    public void withCustomAnnotationThatIsItselfAnnotatedWithTheRuleAnnotation() throws Throwable {
+        ruleDefinitionValidator.validateRuleDefinition(new AnnotatedRuleWithMetaRuleAnnotation());
+    }
+
     /*
      * Conditions methods tests
      */
diff --git a/easyrules-core/src/test/java/org/easyrules/core/RuleProxyTest.java b/easyrules-core/src/test/java/org/easyrules/core/RuleProxyTest.java
new file mode 100644
index 0000000..73b0f98
--- /dev/null
+++ b/easyrules-core/src/test/java/org/easyrules/core/RuleProxyTest.java
@@ -0,0 +1,20 @@
+package org.easyrules.core;
+
+import org.easyrules.annotation.AnnotatedRuleWithMetaRuleAnnotation;
+import org.easyrules.api.Rule;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+public class RuleProxyTest {
+
+    @Test
+    public void proxyingHappensEvenWhenRuleIsAnnotatedWithMetaRuleAnnotation() {
+        AnnotatedRuleWithMetaRuleAnnotation rule1 = new AnnotatedRuleWithMetaRuleAnnotation();
+
+        Rule rule = RuleProxy.asRule(rule1);
+
+        assertNotNull(rule.getDescription());
+        assertNotNull(rule.getName());
+    }
+}
diff --git a/easyrules-core/src/test/java/org/easyrules/util/UtilsTest.java b/easyrules-core/src/test/java/org/easyrules/util/UtilsTest.java
new file mode 100644
index 0000000..4df9b05
--- /dev/null
+++ b/easyrules-core/src/test/java/org/easyrules/util/UtilsTest.java
@@ -0,0 +1,72 @@
+package org.easyrules.util;
+
+import org.junit.Test;
+
+import java.lang.annotation.*;
+
+import static org.junit.Assert.*;
+
+public class UtilsTest {
+
+    @Test
+    public void findAnnotationWithClassWhereAnnotationIsPresent() {
+        Annotation foo = Utils.findAnnotation(Foo.class, AnnotationIsPresent.class);
+
+        assertCorrectAnnotationIsFound(Foo.class, foo);
+    }
+
+    @Test
+    public void findAnnotationWithClassWhereAnnotationIsPresentViaMetaAnnotation() {
+        Annotation foo = Utils.findAnnotation(Foo.class, AnnotationIsPresentViaMetaAnnotation.class);
+
+        assertCorrectAnnotationIsFound(Foo.class, foo);
+    }
+
+    @Test
+    public void findAnnotationWithClassWhereAnnotationIsNotPresent() {
+        Annotation foo = Utils.findAnnotation(Foo.class, Object.class);
+
+        assertNull(foo);
+    }
+
+    @Test
+    public void isAnnotationPresentWithClassWhereAnnotationIsPresent() {
+        assertTrue(Utils.isAnnotationPresent(Foo.class, AnnotationIsPresent.class));
+    }
+
+    @Test
+    public void isAnnotationPresentWithClassWhereAnnotationIsPresentViaMetaAnnotation() {
+        assertTrue(Utils.isAnnotationPresent(Foo.class, AnnotationIsPresentViaMetaAnnotation.class));
+    }
+
+    @Test
+    public void isAnnotationPresentWithClassWhereAnnotationIsNotPresent() {
+        assertFalse(Utils.isAnnotationPresent(Foo.class, Object.class));
+    }
+
+    private static void assertCorrectAnnotationIsFound(
+            Class expectedAnnotationType, Annotation actualAnnotation) {
+
+        assertNotNull(actualAnnotation);
+        assertEquals(expectedAnnotationType, actualAnnotation.annotationType());
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.TYPE)
+    private @interface Foo {
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.TYPE)
+    @Foo
+    private @interface MetaFoo {
+    }
+
+    @Foo
+    private static final class AnnotationIsPresent {
+    }
+
+    @MetaFoo
+    private static final class AnnotationIsPresentViaMetaAnnotation {
+    }
+}